# Operations in nested lists

New to Mathematica, I have a nested list containing many lists(A) of 16 lists(B) of 3 integers(C). I wish to put in each (Aj, Bi, C2) the result of (Aj, Bi-1, C2)+(Aj, Bi, C1). I could do it with a loop, or a spreadsheet, but is there a more elegant way to do this using functions like Accumulate? I simplified the data here:

 myList =
{{{a, b}, {c, d}, {e, f}},
{{g, h}, {i, j}, {k, l}},
{{m, n}, {o, p}, {q, r}},
{{s, t}, {u, v}, {w, x}}}


A simple replacement test function before using values of other elements:

myF[x_] := x*2
ReplacePart[myList, {_, _, 2} -> xx]


Result:

{{{a, xx}, {c, xx}, {e, xx}},
{{g, xx}, {i, xx}, {k, xx}},
{{m, xx}, {o, xx}, {q, xx}},
{{s, xx}, {u, xx}, {w, xx}}}


I tried many expressions in the function without success.

ReplacePart[myList, {_, _, 2} -> myF[ ??? ]]


should result:

{{{a, 2b}, {c, 2d}, {e, 2f}},
{{g, 2h}, {i, 2j}, {k, 2l}},
{{m, 2n}, {o, 2p}, {q, 2r}},
{{s, 2t}, {u, 2v}, {w, 2x}}}


How could Accumulate give this?

{{{a, a}, {c, a+c}, {e, a+c+e}},
{{g, g}, {i, g+i}, {k, g+i+k}},
{{m, m}, {o, m+o}, {q, m+o+q}},
{{s, s}, {u, s+u}, {w, s+u+w}}}


Thanks!

• The solutions are so concise and powerful! It's very exiting to discover in the same time Mathematica and Stackexchange. Thank you march, ubpdqn and eldo for your answers. – makundo Dec 6 '15 at 21:32
• For the first one, after Mr Wizard here: myList.{{1, 0}, {0, 2}}. Very fast, I think. – user1066 Jul 12 '16 at 18:06

myList = {
{{a, b}, {c, d}, {e, f}},
{{g, h}, {i, j}, {k, l}},
{{m, n}, {o, p}, {q, r}},
{{s, t}, {u, v}, {w, x}}
};


For the first, one could do

MapAt[2 # &, myList, {All, All, 2}]
(* {
{{a, 2*b}, {c, 2*d}, {e, 2*f}},
{{g, 2*h}, {i, 2*j}, {k, 2*l}},
{{m, 2*n}, {o, 2*p}, {q, 2*r}},
{{s, 2*t}, {u, 2*v}, {w, 2*x}}
} *)


or with your

myF[x_] := x*2


do

MapAt[myF, myList, {All, All, 2}]


As for the second, here's another version that is basically equivalent to ubpdqn's, but slightly less verbose:

Thread@{#, Accumulate@#} &@#[[All, 1]] & /@ myList


Or, a trickier variant:

Thread@{#, Accumulate@#} & @@@ Thread /@ myList


Here's a version that uses ReplaceAll, with a dummy variable to update so that we don't have to Accumulate:

Map[
Module[{var = 0}, # /. {a_, b_} :> (var = var + a; {a, var})] &
, myList
]


However, ReplaceAll with this pattern will fail when the sub-list is two elements long. Instead, we use Replace, and make the code more concise:

Module[{var = 0},
Replace[#, {a_, b_} :> {a, var = var + a}, 2]
] & /@ myList

• Completely new to me that one can combine MapAt with All. Very handy, +1 – eldo Dec 6 '15 at 21:12

I believe this achieves your goal:

Join @@ Map[Transpose[{#, Accumulate@#}] &, Transpose /@ myList, {2}]


Transpose is a very helpful function. This also exploits the level argument for Map and Join just recombines.

There are many ways to do things in Mathematica. There will no doubt other approaches.

• This will be faster on packed arrays: Transpose[{#, Accumulate@#} &@First@Transpose[myList, {3, 2, 1}], {3, 2, 1}]. – Michael E2 Dec 6 '15 at 21:10

ReplacePart is not the natural choice to apply a function to the innermost matrix elements. Simple and straightforward is ReplaceAll:

myList /. {a_, b_} :> {a, myF @ b} // MatrixForm


With very large matrices ReplaceAll can get slow. In this case one can do an "inline" replacement. Since this permanently changes myList we do it with a copy:

copy = myList;

copy[[All, All, 2]] *= 2;


Thanks @MichaelE2 for this terse notation

copy


Accumulate with

Transpose /@ Transpose[{#, Accumulate /@ #}] &[myList[[All, All, 1]]] // MatrixForm


• I think copy[[All, All, 2]] *= 2 will be faster on longer, large packed arrays. (+1) – Michael E2 Dec 6 '15 at 20:57
• Of course, thanks for this valuable advice - will update :) – eldo Dec 6 '15 at 21:05