# Is there a neat code to swap elements of a list?

I want to swap the list to make a new list as follows. The code works but I'm wondering if there is a neat code, or an elegant way to do this.

list = {1, -1, -1, 1, 0, 0, d, -1, 1};
newlist = {Sequence @@ list[[4 ;; 6]], Sequence @@ list[[1 ;; 3]],
Sequence @@ list[[7 ;; 9]]}
• list[[#]] & /@ {4 ;; 6, 1 ;; 3, 7 ;; 9} // Flatten Apr 9, 2021 at 8:42
• Are you concerned about computational efficiency for very long lists?
– A.G.
Apr 9, 2021 at 14:26
• @A.G. that would be good too. What I had in mind was to make it short and easy to understand. Apr 9, 2021 at 14:42
• Then permutations are probably better, in order to avoid duplicating the list.
– A.G.
Apr 9, 2021 at 19:10
• Should this go on Stack Overflow? Apr 9, 2021 at 19:28

Permute exists for reordering lists.

Permute[list, Cycles[{{1, 4}, {2, 5}, {3, 6}}]]

This swaps entries $$1 \leftrightarrow 4$$, $$2 \leftrightarrow 5$$ and $$3 \leftrightarrow 6$$.

The necessary permutation can be found using FindPermutation:

FindPermutation[Range@9, {4, 5, 6, 1, 2, 3, 7, 8, 9}]

Cycles[{{1, 4}, {2, 5}, {3, 6}}]

• list[[{4, 5, 6, 1, 2, 3, 7, 8, 9}]] works too. Apr 9, 2021 at 10:35

At least shorter:

Flatten@Partition[list, 3][[{2, 1, 3}]]

Id suggest using TakeList

TakeList[ist, {{4, 6}, 3, All}]
TakeList[ist, {{4, 6}, {1, 3}, {1, 3}}]

The indices need to be relative to those elements that are not yet taken.

If you have absolute indices given:

ist = Range[20];
parts = {{5, 6}, {9, 13}, {1, 4}, {19, 20}, {14, 18}};

Catenate[ist[[# ;; #2]] & @@@ parts]
list = Range[9];
swap =  {{2, 5}, {3, 6}};

Fold[SubsetMap[RotateRight, #1, #2] &, list, swap]

{1, 5, 6, 4, 2, 3, 7, 8, 9}

list = Range[9];
swap = {{2, 5}, {3, 6}};