Mathematica Asked on October 22, 2021
Suppose I have a list of multiple sublists:
testlist={{1,1,1,0,0,0,1,1,1,0,1,1},{1,0,0,1,1,1,1,0,1,1,1,0}}
I want to replace given sequences without creating new sublists and without flattening.
For example, I’d like to replace all instances of {1,0,1} within all sublists with {1,1,1}.
The final output for the above should be:
{{1,1,1,0,0,0,1,1,1,1,1,1,},{1,0,0,1,1,1,1,1,1,1,1,0}}
Here are some attempts to show the issue:
testlist = {{1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1}, {1, 0, 0, 1, 1, 1,
1, 0, 1, 1, 1, 0}}
Replace[testlist, {1, 0, 1} :> {1, 1,
1}, {2}]; (* This does nothing; Replace doesn't accept sequences *)
Replace[testlist,
1 :> {2, 2}, {2}] (* Even if it did work, Replace creats new
sublists *)
(* Output:
{{{2,2},{2,2},{2,2},0,0,0,{2,2},{2,2},{2,2},0,{2,2},{2,2}},{{2,2},0,0,
{2,2},{2,2},{2,2},{2,2},0,{2,2},{2,2},{2,2},0}} *)
ReplaceAll[{1, 0, 1} -> {1, 1, 1}][testlist];
testlist /. {{1, 0, 1} -> {1, 1,
1}}; (* These two both do nothing: same reason *)
testlist //. 0 -> 2 (* This works as you'd expect *)
(* Output: {{1,1,1,2,2,2,1,1,1,2,1,1},{1,2,2,1,1,1,1,2,1,1,1,2}} *)
testlist //. {Sequence[1, 0, 1] ->
Sequence[1, 1, 1]}; (* This does nothing *)
f1[x_List] := 2*x
f1@testlist[[All]] (*This works as you'd expect*)
(* Output: {{2,2,2,0,0,0,2,2,2,0,2,2},{2,0,0,2,2,2,2,0,2,2,2,0}} *)
f2[x_List] := SequenceReplace[x, {1, 0, 1} -> Sequence[1, 1, 1]]
f2@testlist[[All]]; (*This does nothing*)
f2 @@@ testlist (* This doesn't work *)
(* Output: {f2[1,1,1,0,0,0,1,1,1,0,1,1],f2[1,0,0,1,1,1,1,0,1,1,1,0]} *)
SequenceReplace[
Flatten@testlist, {1, 0, 1} ->
Sequence[1, 1, 1]] (* This works provided there are no sublists *)
(* Output: {1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0} *)
testlist /. {1 ->
Sequence @@ {2,
2}}(* This works and makes a replacement within the desired
sublists *)
(* Output:
{{2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,0,2,2,2,2},{2,2,0,0,2,2,2,2,2,2,2,2,0,
2,2,2,2,2,2,0}} *)
testlist /. {Sequence[1, 0, 1] ->
Sequence @@ {1, 1, 1}} (* This does nothing *)
This feels like it should be simple, but all the documentation I can find only provides solutions for single lists, not sublists, and everything I find that says "You can do this for any level you want" doesn’t work for sequences.
I can force the answer with a For loop, but I’d like to extend this code to lists with thousands of numbers, and then run it for multiple lists, which doesn’t have acceptable scaling.
Another way
SequenceReplace[{1, 0, 1} -> {1, 1, 1}] /* Flatten /@ testlist
Inspired by @carl woll's comment
SequenceReplace[{1, 0, 1} -> Splice[{1, 1, 1}]] /@ testlist
Answered by Rohit Namjoshi on October 22, 2021
You can use pattern matching with BlankNullSequence
testlist //. {List[a___,1,0,1,b___] :> List[a,1,1,1,b]}
{{1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0}}
Answered by Hausdorff on October 22, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP