Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum values of similar keys inside two nested dictionary in python

I have nested dictionary like this:

data = {
    "2010":{
            'A':2,
            'B':3,
            'C':5,
            'D':-18,
        },
    "2011":{
            'A':1,
            'B':2,
            'C':3,
            'D':1,
        },
    "2012":{
            'A':1,
            'B':2,
            'C':4,
            'D':2
        }
    }

In my case, i need to sum all values based on its similar keys in every year, from 2010 till 2012.. So the result i expected should be like this:

data = {'A':4,'B':7, 'C':12, 'D':-15}
like image 791
Faizalprbw Avatar asked Mar 09 '17 10:03

Faizalprbw


People also ask

Can you have two of the same keys in a dictionary Python?

The straight answer is NO. You can not have duplicate keys in a dictionary in Python.

How do you compare keys and values of two dictionaries in Python?

The compare method cmp() is used in Python to compare values and keys of two dictionaries. If method returns 0 if both dictionaries are equal, 1 if dic1 > dict2 and -1 if dict1 < dict2.

Can 2 values have the same key in dictionary?

In python, if we want a dictionary in which one key has multiple values, then we need to associate an object with each key as value. This value object should be capable of having various values inside it. We can either use a tuple or a list as a value in the dictionary to associate multiple values with a key.


2 Answers

You can use collections.Counter() (works only for positive values!):

In [17]: from collections import Counter
In [18]: sum((Counter(d) for d in data.values()), Counter())
Out[18]: Counter({'C': 12, 'B': 7, 'A': 4, 'D': 3})

Note that based on python documentation Counter is designed only for use cases with positive values:

The multiset methods are designed only for use cases with positive values. The inputs may be negative or zero, but only outputs with positive values are created. There are no type restrictions, but the value type needs to support addition, subtraction, and comparison. The elements() method requires integer counts. It ignores zero and negative counts.

So if you want to get a comprehensive result you can do the summation manually. The collections.defaultdict() is a good way for getting around this problem:

In [28]: from collections import defaultdict

In [29]: d = defaultdict(int)

In [30]: for sub in data.values():
   ....:     for i, j in sub.items():
   ....:         d[i] += j
   ....:         

In [31]: d
Out[31]: defaultdict(<class 'int'>, {'D': -15, 'A': 4, 'C': 12, 'B': 7})
like image 50
Mazdak Avatar answered Nov 09 '22 10:11

Mazdak


Try this,

reduce(lambda x, y: dict((k, v + y[k]) for k, v in x.iteritems()), data.values())

Result

{'A': 4, 'B': 7, 'C': 12, 'D': -15}
like image 34
Rahul K P Avatar answered Nov 09 '22 11:11

Rahul K P