6
$\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$

2 Answers 2

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

Mathematica graphics

$\endgroup$
2
  • 7
    $\begingroup$ Or Total[myList], which is the same thing. $\endgroup$
    – Roman
    Apr 28, 2019 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, 2019 at 3:45
6
$\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$
3
  • $\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, 2019 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, 2019 at 12:14
  • $\begingroup$ I believe the y-axis should be labeled Time and not Speed. $\endgroup$
    – quoniam
    Aug 29 at 7:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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