# Efficiently exchange elements between two lists

I have two lists with equal length, and I want to exchange the elements on every even positions. For example,

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


will return

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


It has to be able to deal with length of both even and odd; and in the real case the list is very long. I am not satisfied with naive approaches with indexing and partitioning because they are slow. Is there any fast approaches?

• Closely related: (3069) Aug 5, 2016 at 11:48

list[[All, 2 ;; ;; 2]] = Reverse @ list[[All, 2 ;; ;; 2]];
list

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


or list[[-1 ;; 1 ;; -1, 2 ;; ;; 2]].

ps. keep in mind that this changes list.

• Thanks! Your solution is the fastest Aug 5, 2016 at 9:42
• I modified your code to use the backward-compatible form. I also find this more readable as one can get lost in all the semicolons. I hope you do not mind. Aug 5, 2016 at 11:49
• You could also eliminate Reverse with: list[[All, 2 ;; ;; 2]] = list[[{2, 1}, 2 ;; ;; 2]];, or perhaps more explicitly list[[{1, 2}, 2 ;; ;; 2]] = list[[{2, 1}, 2 ;; ;; 2]]; Aug 5, 2016 at 11:56
ClearAll[f1]
f1 = Module[{l2 = Transpose@#}, l2 = Transpose[MapAt[Reverse, l2, {2 ;; ;; 2}]]] &;

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


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

Or

ClearAll[f2]
f2 = Module[{l2 = #},
l2[[All, 2 ;; ;; 2]] = Reverse /@ Transpose[l2[[All, 2 ;; ;; 2]]]; l2] &;

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


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

• I knew spanning specification worked with Take (was designed for?), but it obviously works with MapAt as well. But a span of elements is generally not equivalent to a list of positions, right?
– BoLe
Aug 5, 2016 at 10:02

I think Reverse is better suited for long lists. When the lists that need be reversed have length 2, I would do this:

L = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
Transpose[MapAt[#[[{2, 1}]] &, Transpose[L], 2 ;; ;; 2]]

• I knew spanning specification worked with Take (was designed for?), but it obviously works with MapAt as well. But a span of elements is generally not equivalent to a list of positions, right?
– BoLe
Aug 5, 2016 at 10:03
lst = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
Module[{i = 1},
Transpose@MapThread[If[EvenQ[i++], Reverse@{##}, {##}] &, lst]
]
(* {{1, 7, 3, 9, 5}, {6, 2, 8, 4, 10}} *)