3
$\begingroup$

I know, the title may seem complicated. I have this list:

myList = { {1, 0},{2, 3},{4, 1} }

I want to sum all the sublists (element by element) to obtain this list:

sumList = {7,4}

Where the first element is 1+2+4 and the second is 0+3+1. How can i obtain this? In my project i won't know a priori neither the number of sublists nor the number of elements in the sublists. The only thing i know is that all the sublists have the same number of elements.

$\endgroup$
4
$\begingroup$
myList = {{1, 0}, {2, 3}, {4, 1}}
Plus @@ myList

Mathematica graphics

$\endgroup$
  • 5
    $\begingroup$ Or Total[myList], which is the same thing. $\endgroup$ – Roman Apr 28 at 18:59
  • 2
    $\begingroup$ Using Plus @@ myList unpacks myList, so for large packed arrays, using Total will be much faster. $\endgroup$ – Carl Woll Apr 30 at 3:45
3
$\begingroup$

An alternative is

Plus @@ # & /@ Transpose@myList

This is twice as slow for small lists like yours. For big lists it is more efficient:

biglist = RandomInteger[{0, 9}, {10000, 2}];

Plus @@ biglist // RepeatedTiming
Plus @@ # & /@ Transpose@biglist // RepeatedTiming

0.0068

0.0013


(Revised) Update

(see edits for history)

For lists containing more than ~14 (n = 2) sublists my method is quicker than Plus@@. However, as @Carl Woll points out, one must consider array unpacking with certain Mathematica functions.

(a good discussion of packed versus unpacked arrays can be found here)

sublistsum1 = 
 Transpose@
 Table[Module[{list, plist, tlist, totlist, ttotlist}, 
 list = RandomInteger[{0, 9}, {x, 2}];
 plist = RepeatedTiming[Plus @@ list][[1]];
 tlist = RepeatedTiming[Plus @@ # & /@ Transpose@list][[1]];
 totlist = RepeatedTiming[Total[list]][[1]];
 ttotlist = RepeatedTiming[Total[#] & /@ Transpose@list][[1]];

 {{x, plist}, {x, tlist}, {x, totlist}, {x, ttotlist}}], 
 {x, 2, 30, 2}
 ];

ListLinePlot[sublistsum1, PlotStyle -> {Red, Blue, Green, Orange}, 
 PlotLegends -> 
  {"Plus@@...", "Plus@@#&/@Transpose@...", 
   "Total...", "Total[#]&/@Transpose@..."}, 
 AxesLabel -> {"Number of sublists\n(of length 2)", "Speed (seconds)"}]

enter image description here

For the Plus-based methods as the sublists get longer the advantage of transposing the data diminishes.

Regardless, Total[..] is the fastest method.

sublistsum2 = 
 Transpose@
  Table[Module[{list, plist, tlist, totlist, ttotlist}, 
   list = RandomInteger[{0, 9}, {10000, x}];
   plist = RepeatedTiming[Plus @@ list][[1]];
   tlist = RepeatedTiming[Plus @@ # & /@ Transpose@list][[1]];
   totlist = RepeatedTiming[Total[list]][[1]];
   ttotlist = RepeatedTiming[Total[#] & /@ Transpose@list][[1]];
   {{x, plist}, {x, tlist}, {x, totlist}, {x, ttotlist}}], 
   {x, 10, 70, 10}];

  ListLinePlot[sublistsum2, PlotStyle -> {Red, Blue, Green, Orange}, 
   PlotLegends -> {"Plus@@...", 
                   "Plus@@#&/@Transpose@...", 
                   "Total...", 
                   "Total[#]&/@Transpose@..."}, 
   AxesLabel -> {"Length of sublists\n\[Times]10000", "Speed (seconds)"}]

enter image description here

$\endgroup$
  • $\begingroup$ Very interesting, thank you! I'm new into Mathematica and i'm still trying to figure out the syntax. I will keep your answer for next projects, because i have to manage large amounts of data. $\endgroup$ – alcor Apr 30 at 10:38
  • $\begingroup$ I'm glad it's useful. Functional manipulation of lists is one of the great joys of Mathematica. $\endgroup$ – geordie Apr 30 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.