Tengo una lista de tuplas:

[(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]

Y quiero sumar el lado derecho de las tuplas donde el lado izquierdo es igual, y ponerlo en otra lista de tuplas, así que para la lista anterior obtendré:

[(0,2),(1,1),(2,1),(3,2),(4,3),(5,2)]

Intenté esto:

k=0
for i,TCtup in enumerate(wordsMatchingList):
    if wordsMatchingList[i][0]==k:
        TC_matches+=wordsMatchingList[i][1]
        print("k: {} /// TC_matches: {}".format(k,TC_matches)) #for checking
    else:
        groupedWordsMatchingList.append(tuple((k,TC_matches)))
        TC_matches=0
        k+=1

Pero de k = 1 simplemente se repite una vez menos por cada k debido a la condición else.

Gracias

0
Matan 10 sep. 2018 a las 02:01

6 respuestas

La mejor respuesta

Otra forma más

t.sort(key=lambda x: x[0]) #sort before groupby (required)
g=itertools.groupby(t, lambda x: x[0])
new_l = []
for k,v in g:
    new_l.append((k, sum([x[1] for x in v])))
2
VanTan 12 sep. 2018 a las 18:03

Si se garantiza que sus tuplas se ordenan de esta manera, todos los (0, x), luego todos los (1, x), etc., puede usar groupby:

>>> xs = [(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]
>>> from itertools import groupby
>>> from operator import itemgetter
>>> groups = groupby(xs, key=itemgetter(0))
>>> ys = [(key, sum(map(itemgetter(1), group))) for key, group in groups]

Si no lo son , pero puede ordenarlos (tiene una lista, no solo un iterativo arbitrario, y no es tan grande que el tiempo log-lineal sea demasiado costoso):

>>> groups = groupby(sorted(xs, key=itemgetter(0)), key=itemgetter(0))

Si no puede ordenarlos, puede acumular manualmente los totales a medida que avanza:

>>> from collections import Counter
>>> totals = Counter()
>>> for k, v in xs:
...     totals[k] += v
>>> ys = list(totals.items())
3
abarnert 9 sep. 2018 a las 23:10

Recomiendo usar una biblioteca con una función groupby. pandas, por ejemplo, puede ser útil

>>> s = pd.DataFrame(list_)
>>> s.groupby(0, as_index=False).sum().agg(tuple,1).tolist()

[(0, 2), (1, 1), (2, 1), (3, 2), (4, 3), (5, 2)]
0
rafaelc 9 sep. 2018 a las 23:05

Otro enfoque es utilizar un defaultdict (de colecciones ) y para iterar la lista de tuplas.

from collections import defaultdict

lst = [(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]

d = defaultdict(int)

for (u,v) in lst:
    d[u]+=v

# list(d.items()) [(0, 2), (1, 1), (2, 1), (3, 2), (4, 3), (5, 2)]
2
abc 9 sep. 2018 a las 23:09
In [5]: [(j, sum([i[1] for i in a if i[0] == j])) for j in set([i[0] for i in a])]
Out[5]: [(0, 2), (1, 1), (2, 1), (3, 2), (4, 3), (5, 2)]
0
Osman Mamun 9 sep. 2018 a las 23:29
lst = [(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]
[(i,sum([q[1] for q in lst if q[0] == i])) for i in range(lst[-1][0]+1)]

Da:

[(0,2),(1,1),(2,1),(3,2),(4,3),(5,2)]
0
Jonas Wolff 9 sep. 2018 a las 23:46