Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose I have a list of lists with different lengths, sorted from longest to shortest

 myLists = Sort[Table[RandomReal[1, RandomInteger[50]], {25}], Length@#1 > Length@#2 &];

I would like to add up all the first elements, then all the second, and so on elements for each list that has the required number of elements.

For example if my lists are

{
 {1,2,3},
 {4,5},
 {6}
}

Then I want to return

{11,7,3}

The following code performs this using For loops, but I am trying to figure out a better way of doing this.

sums = Table[0, {Max[Length /@ a]}];
(* For each row element up to the length of the longest list *)
For[j = 1, j <= Max[ Length /@ a], j++,
(* For each list *)
     For[k = 1, k <= Length[a], k++,
(* Add the element to the correct sum if it exists *)
            If[Length[a[[k]]] >= j,
                 sums[[j]] = sums[[j]] + a[[k, j]],
                 Break[]
              ]
        ]
   ]
share|improve this question
1  
wouldn't it be easier to simply pad every thing to the right length with 0 and then add? Or are zeros appropriate values that can exist in your ragged length list? –  tkott Nov 15 '12 at 20:09
3  
We have just had a question that requires a similar solution. One way is to use Flatten to transpose a 'ragged' array. For example Total /@ Flatten[list, {2}] => {11, 7, 3} –  TomD Nov 15 '12 at 20:14
    
Thanks guys, looks like Total /@ Flatten[list,{2}] will do the trick. So much simplier! –  David Slater Nov 15 '12 at 20:30
add comment

3 Answers

up vote 6 down vote accepted

The second argument of Flatten can be used to transpose ragged lists (also see this answer by Leonid). With this, you can use the second argument of Total to sum each sublist. The following is similar to my comment here:

list = {{1, 2, 3}, {4, 5}, {6}} 
list ~Flatten~ {2} ~Total~ {2}
(* {11, 7, 3} *)
share|improve this answer
add comment

One solution is to use PadRight[] to make a square array (with for example Empty to fill in the blank spots), then Transpose[] it and delete all the Empty's. Finally, you can Total[] all the rows.

Random data:

a = RandomInteger[{0, 20}, #] & /@ Reverse[Range[10]];

Then:

Map[Total, 
 DeleteCases[#, x_ /; x === Empty] & /@ 
  Transpose[PadRight[a, {10, 10}, Empty]]]

It's a bit of a workaround, but it does the trick.

share|improve this answer
add comment

As A. Goossens mentions, one can use PadRight[] as an alternative, though in fact one can leverage the fact that

PadRight[list] pads a ragged array list with zeros to make it full.

so:

Total[PadRight[{{a, b}, {c, d, e, f}, {g, h, i}}]]
   {a + c + g, b + d + h, e + i, f}
share|improve this answer
    
I explicity used Empty so the data stays the same even if there are already zeros in it. For the solution it doesn't make any difference, that's true. –  A. Goossens Nov 16 '12 at 7:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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