# Change part of a list

I'm starting in Mathematica. I would like your help to solve the following question (which is really basic):

Whenever the sequence 1, 2, 1 appears in a given list, I want to change this part of the list to the sequence 2, 1, 2.

For example, given the list lis1 = {1, 2, 3, 4, 1, 2, 3, 1, 2, 1}, I want to get the list lis2 = {1, 2, 3, 4, 1, 2, 3, 2, 1, 2}.

Yes, for example my list is lis3 = {1,2,3,4,3, 1,2,1, 3,2}. I want to get the list lis4 = {1,2,3,4,3, 2,1,2, 3,2}

How can I achieve this?

• What do you want the result to be if the input list is {1,2,1,2,1}? Make sure the implementation you choose does the desired thing on examples like this. – Greg Martin Dec 28 '19 at 16:39

SequenceReplace[{1, 2, 1} -> Sequence[2, 1, 2]] @ lis1


{1, 2, 3, 4, 1, 2, 3, 2, 1, 2}

SequenceReplace[{1, 2, 1} -> Sequence[2, 1, 2]] @ lis3


{1, 2, 3, 4, 3, 2, 1, 2, 3, 2}

Alternative methods:

MapAt[3 - # &, #, Span @@@ SequencePosition[#, {1, 2, 1}]] &@lis1


{1, 2, 3, 4, 1, 2, 3, 2, 1, 2}

MapAt[3 - # &, #, Span @@@ SequencePosition[#, {1, 2, 1}]] &@lis3


{1, 2, 3, 4, 3, 2, 1, 2, 3, 2}

Fold[SubsetMap[3 - # &, ##] &][#, Span @@@ SequencePosition[#, {1, 2, 1}]] &@lis1


{1, 2, 3, 4, 1, 2, 3, 2, 1, 2}

Fold[SubsetMap[3 - # &, ##] &][#, Span @@@ SequencePosition[#, {1, 2, 1}]] &@lis3


{1, 2, 3, 4, 3, 2, 1, 2, 3, 2}

Part assignment:

Module[{l = #},
Do[l[[i]] = {2, 1, 2}, {i, Span @@@ SequencePosition[#, {1, 2, 1}]}]; l]&@lis1


{1, 2, 3, 4, 1, 2, 3, 2, 1, 2}

Module[{l = #},
Do[l[[i]] = {2, 1, 2}, {i, Span @@@ SequencePosition[#, {1, 2, 1}]}]; l] &@lis3


{1, 2, 3, 4, 3, 2, 1, 2, 3, 2}

Patterns also work.

list = {1, 3, 5, 4, 5, 3, 1, 2, 1, 3, 4, 1, 2} /. {a___, 1, 2, 1, b___} -> {a, 2, 1, 2, b}


gives:

{1, 3, 5, 4, 5, 3, 2, 1, 2, 3, 4, 1, 2}

• What kind of patterns? What is the explanation for why this solution works? – Peter Mortensen Dec 28 '19 at 1:02