ustroetz
ustroetz

Reputation: 6312

Sum of dict elements

I have a dictionary of names and ages. Some of the names are identical. I want to sum the age of the names that are identical.

My fake data looks like this:

pete: 33
ann: 7
ruth: 3
ann: 5
austin: 90

In the examples there are two anns. So I want to sum the ages of the two anns. Currently I have a dictionary:

dict = {'pete':33,'ann':7,'ruth':3,'ann':5,'austin':90}

My result should look like this

dict = {'pete':33,'ann':12,'ruth':3,'austin':90}

pete: 33
ann: 12
ruth: 3
austin: 90

I think to put the data in a dictionary like this isn't the best solution. What is a good other solution to store the data and process them into the output?

Upvotes: 3

Views: 139

Answers (3)

Óscar López
Óscar López

Reputation: 236170

Your fake data can not look like that. it's impossible to have two entries with the same key in a dictionary, perhaps you meant to use a different data structure? (not a dictionary). But if your data looked like this:

input = [('pete', 33), ('ann',7), ('ruth',3), ('ann',5), ('austin',90)]

Then a defaultdict would be a good idea:

from collections import defaultdict
d = defaultdict(int)

for k, v in input:
    d[k] += v

d
=> defaultdict(<type 'int'>, {'pete': 33, 'ann': 12, 'ruth': 3, 'austin': 90})

Or using a Counter:

from collections import Counter
d = Counter()

for k, v in input:
    d.update({k:v})

d
=> Counter({'austin': 90, 'pete': 33, 'ann': 12, 'ruth': 3})

And yet another solution, without importing extra libraries:

d = {}
for k, v in input:
    if k in d:
        d[k] += v
    else:
        d[k] = v

d
=> {'pete': 33, 'ann': 12, 'ruth': 3, 'austin': 90}

Upvotes: 4

Instead of using dictionary, you need to use a list of tuples

pairs = [ ('pete', 33), ('ann', 7), ('ruth', 3), ('ann', 5), ('austin', 90) ]

Then you can calculate the sum using a defaultdict:

from collections import defaultdict
answer = defaultdict(int)
for name, number in pairs:
    answer[name] += number

print(answer)

The defaultdict works by calling the given function (int) to give the default value for any keys that do not exist (int() returns conveniently 0); then for each iteration the number is added to that.

Upvotes: 3

John Kugelman
John Kugelman

Reputation: 362197

data = [('pete', 33), ('ann', 7), ('ruth', 3), ('ann', 5), ('austin', 90)]

Since dicts can't contain duplicate keys, you could start out with a list of tuples instead.

from collections import defaultdict
combined = defaultdict(int)

for name, age in data:
    combined[name] += age

Then build the dict using defaultdict. The trick is that defaultdict(int) creates a dict whose entries default to 0 so you don't have to deal with non-existent keys.

Upvotes: 3

Related Questions