1

How do you get the sum of second and third values in a list of tuples grouped by the first value?

I.e:

list_of_tuples = [(1, 3, 1), (1, 2, 4), (2, 1, 0), (2, 2, 0)]

expected_output = [(1, 5, 5), (2, 3, 0)]

I found several great answers on StackOverflow doing this found tuples with two values, but couldn't figure out how to adjust them for summing both second and third values.

One of the good answers for just the second value was this:

def sum_pairs(pairs):
sums = {}
for pair in pairs:
    sums.setdefault(pair[0], 0)
    sums[pair[0]] += pair[1]
return sums.items()
Wessi
  • 1,702
  • 4
  • 36
  • 69

3 Answers3

3

You could also do it like this:

list_of_tuples = [(1, 3, 1), (1, 2, 4), (2, 1, 0), (2, 2, 0)]

# create empty dictionary to store data
sums = {}

# iterate over list of typles
for pair in list_of_tuples:

  # create new item in dictionary if it didnt exist
  if pair[0] not in sums: sums[pair[0]] = [pair[0], 0 ,0]

  # sum the values
  sums[pair[0]][1] += pair[1]
  sums[pair[0]][2] += pair[2]

#print resulting tuple   
print(tuple(sums.values()))
Vico
  • 579
  • 3
  • 13
1

You can use itertools.groupby to group based on the first item, and then take the cumulative sums of all the last two items in each group:

from itertools import groupby

list_of_tuples = [(1, 3, 1), (1, 2, 4), (2, 1, 0), (2, 2, 0)]
lst = [(k,)+tuple(sum(x) for x in zip(*g))[1:] 
                         for k, g in groupby(list_of_tuples, lambda x: x[0])]
print(lst)
# [(1, 5, 5), (2, 3, 0)]
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
1

Use a defaultdict as a grouper:

>>> from collections import defaultdict
>>> grouper = defaultdict(lambda: (0,0))
>>> list_of_tuples = [(1, 3, 1), (1, 2, 4), (2, 1, 0), (2, 2, 0)]
>>> for a, b, c in list_of_tuples:
...     x, y = grouper[a]
...     grouper[a] = (x + b, y + c)
...
>>> grouper
defaultdict(<function <lambda> at 0x102b240d0>, {1: (5, 5), 2: (3, 0)})

Now, you can always get a list of tuples back like this:

>>> [(k, a, b) for k, (a, b) in grouper.items()]
[(1, 5, 5), (2, 3, 0)]
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172