Reputation: 23
x = [(5,3), (8, 3), (7, 3), (5, 4), (2, 4), (3, 4)]
d = {}
[d.__setitem__(d.get(key1,0)+key1,key2) for key1,key2 in x]
print(list(d.items()))
I want to add the first value in the tuple having the same second value. I have written the code, but i am not able to find my mistake. Any ideas ??
Upvotes: 0
Views: 164
Reputation: 29690
Kasramvd already has you covered as for why your approach doesn't work. You could use itertools.groupby
to group by second tuple elements, then sum the first elements with operator.itemgetter
.
{k: sum(map(itemgetter(0), g)) for k, g in groupby(x, itemgetter(1))}
Evidently if your list wasn't sorted by second tuple elements as it currently is, you would have to sort first.
Demo
>>> from operator import itemgetter
>>> from itertools import groupby
>>> x = [(5,3), (8, 3), (7, 3), (5, 4), (2, 4), (3, 4)]
>>> {k: sum(map(itemgetter(0), g)) for k, g in groupby(x, itemgetter(1))}
{3: 20, 4: 10}
Upvotes: 0
Reputation: 107287
__setitem__
returns None, also your logic is wrong too. You need to categorize your items based on the second value then sum their first value up.
You can use collections.defaultdict()
for categorization:
In [13]: x = [(5,3), (8, 3), (7, 3), (5, 4), (2, 4), (3, 4)]
In [16]: from collections import defaultdict
In [17]: d = defaultdict(int)
In [18]: for i, j in x:
....: d[j] += i
....:
In [19]: d
Out[19]: defaultdict(<class 'int'>, {3: 20, 4: 10})
You could also use itertools.groupby()
within a dictionary comprehension:
In [28]: from itertools import groupby
In [29]: from operator import itemgetter
In [30]: {k: sum(i for i, _ in g) for k, g in groupby(x, itemgetter(1))}
Out[30]: {3: 20, 4: 10}
Note that if your list is not sorted based on second item you need to sort it based on that second item before passing to groupby()
function. (In that case this solution would be so inefficient against the defaultdict
one)
Upvotes: 2