# 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. Dec 6, 2015 at 21:32
• For the first one, after Mr Wizard here: myList.{{1, 0}, {0, 2}}. Very fast, I think. Jul 12, 2016 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, 2015 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}]. Dec 6, 2015 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) Dec 6, 2015 at 20:57
• Of course, thanks for this valuable advice - will update :)
– eldo
Dec 6, 2015 at 21:05