2

I am trying to write a function that add all of the the inner key and value pairs of a nested dictionary.

This is what I would pass in

Pets = {'family1':{'dogs':2,'cats':3,'fish':1},
       'family2':{'dogs':3,'cats':2}}

This is what I would expect as the result

{'dogs': 5, 'cats': 5, 'fish': 1}

This is the loop I have written so far

def addDict(d):
    d2 = {}
    for outKey, inKey in d.items():
        for inVal in inKey:
            print(inVal, " ", inKey[inVal])
            d2[inVal] = inKey[inVal]
    return d2

This prints

dogs   2
cats   3
fish   1
dogs   3
cats   2

and returns

{'dogs': 3, 'cats': 2, 'fish': 1}

But how can I get the data to be cumulative, because it is just giving me the data from the first dictionary.

4 Answers4

2

You can do something like this,

Pets={'family1': {'cats': 3, 'dogs': 2, 'fish': 1},
 'family2': {'cats': 2, 'dogs': 3}}
d={}
for i in Pets:
    for j in Pets[i]:
        if j in d:
            d[j] += Pets[i][j]
        else:
            d[j] = Pets[i][j]

print d

>> Output
{'cats': 5, 'dogs': 5, 'fish': 1}
Sanket
  • 744
  • 7
  • 22
2

You can use this:

pets = {'family1':{'dogs':2,'cats':3,'fish':1},
       'family2':{'dogs':3,'cats':2}}

def addDict(d):
    d2 = {}
    for outKey, inKey in d.items():
        for inKey, inVal in inKey.items():
            try:
                d2[inKey] += inVal
            except KeyError:
                d2[inKey] = inVal
    return d2

print(addDict(pets))

Output:

{'dogs': 5, 'cats': 5, 'fish': 1}

This is called as EAFP principle in Python. What you simply do, is try to add the value for a key. If the key is not present, it'll throw a KeyError. Catch that error and insert the key.

Keyur Potdar
  • 7,158
  • 6
  • 25
  • 40
1

You're so close! Just change the = in the part where you set d2's inval to += and it should work. Basically, you want to add the value, not override it. But you also want to check if that key exists first before adding to it. So:

if inVal in d2: d2 [inVal] += inKey [inVal]
else: d2 [inVal] = inKey [inVal]
Levi Lesches
  • 1,508
  • 1
  • 13
  • 23
1

You can use collection.Counter to do all the counting for you

from collections import Counter

def addDict(d):
    c = Counter()
    [c.update(a) for a in d.values()]
    return dict(c)

>>> Pets = {
            'family1':{'dogs':2,'cats':3,'fish':1},
            'family2':{'dogs':3,'cats':2}
            }
>>> addDict(Pets)
>>> {'cats': 5, 'fish': 1, 'dogs': 5}
Sohaib Farooqi
  • 5,457
  • 4
  • 31
  • 43