Reputation: 146
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
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
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
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
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
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
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