Mathematica Asked by KyCygni on August 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.
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}}
Correct answer by Hausdorff on August 22, 2021
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 August 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