Matan
Matan

Reputation: 146

summing tuples in list

I have a list of tuples:

[(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)]

and I want to sum the right-side of tuples where the left-side is equal, and to put it in another tuples-list, so for the above list i'll get:

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

I tried this:

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

but from k=1 it just loop one time less for every k because of the else condition.

thank you

Upvotes: 0

Views: 183

Answers (6)

VanTan
VanTan

Reputation: 657

yet another way,

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

Upvotes: 2

Jonas Wolff
Jonas Wolff

Reputation: 2244

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

gives:

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

Upvotes: 0

Osman Mamun
Osman Mamun

Reputation: 2882

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

Upvotes: 0

abarnert
abarnert

Reputation: 366103

If your tuples are guaranteed to come in order like this—all the (0, x), then all the (1, x), etc.—you can use 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]

If they aren't, but you can sort them (you have a list, not just an arbitrary iterable, and it isn't so huge that log-linear time will be too expensive):

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

If you can't sort them, you can manually build up the totals as you go:

>>> from collections import Counter
>>> totals = Counter()
>>> for k, v in xs:
...     totals[k] += v
>>> ys = list(totals.items())

Upvotes: 3

abc
abc

Reputation: 11949

Another approach is using a defaultdict (from collections) and to iterate the list of tuples.

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

Upvotes: 2

rafaelc
rafaelc

Reputation: 59284

I'd recommend using a library with a groupby function. pandas, for instance, can be useful

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

Upvotes: 0

Related Questions