¿Cómo se obtiene la suma de los valores segundo y tercero en una lista de tuplas agrupadas por el primer valor?

Es decir:

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

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

Encontré varias excelentes respuestas en StackOverflow haciendo esto encontró tuplas con dos valores, pero no pude entender descubra cómo ajustarlos para sumar los valores segundo y tercero.

Una de las buenas respuestas para el segundo valor fue esta:

def sum_pairs(pairs):
sums = {}
for pair in pairs:
    sums.setdefault(pair[0], 0)
    sums[pair[0]] += pair[1]
return sums.items()
1
Wessi 27 oct. 2017 a las 23:08

3 respuestas

La mejor respuesta

También puedes hacerlo así:

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()))
3
Vico 27 oct. 2017 a las 20:21

Puede usar itertools.groupby para agrupar según el primer elemento, y luego tome las sumas acumuladas de los dos últimos elementos en cada grupo:

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)]
1
Moses Koledoye 27 oct. 2017 a las 20:21

Usa una defaultdict como mero:

>>> 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)})

Ahora, siempre puedes obtener una lista de tuplas como esta:

>>> [(k, a, b) for k, (a, b) in grouper.items()]
[(1, 5, 5), (2, 3, 0)]
1
juanpa.arrivillaga 27 oct. 2017 a las 20:17