Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aggregate items in dict

Tags:

python

I have a list like this:

A = [{u'CI': {u'RP': 1}}, {u'CI': {u'RP': 1}},  {u'JI': {u'RP': 1}}]

and I want merge same keys and increment value in dict.

Example:

From these values :

{u'CI': {u'RP': 1}}, {u'CI': {u'RP': 1}}

I will have:

{u'CI': {u'RP': 2}}

final list result is:

A = [{u'CI': {u'RP': 2}}, {u'JI': {u'RP': 1}]
like image 641
user1089362 Avatar asked Dec 09 '11 08:12

user1089362


People also ask

How to sum the values in dictionary in Python?

Using Inbuilt sum() Function Use the sum function to find the sum of dictionary values.

How to sum a list of dictionaries in Python?

To sum the values in a list of dictionaries: Use a generator expression to iterate over the list. On each iteration, access the current dictionary at the specific key. Pass the generator expression to the sum() function.


2 Answers

You can use a defaultdict from collections to help here. This is a dict that will create default values for missing keys. Firstly you'll want a defaultdict that has a default value of 0 to do your aggregation. Next you'll need a defaultdict that has the first kind of defaultdict as its default so you can build up to the two levels.

>>> A = [{u'CI': {u'RP': 1}}, {u'CI': {u'RP': 1}},  {u'JI': {u'RP': 1}}]
>>> B = defaultdict(lambda: defaultdict(int))
>>> for d in A:
...     for (key,d2) in d.iteritems():
...         for (key2, value) in d2.iteritems():
...             B[key][key2] += value
... 
>>> B.items()
[(u'CI', defaultdict(<type 'int'>, {u'RP': 2})), (u'JI', defaultdict(<type 'int'>, {u'RP': 1}))]

If you really want a list of single key dicts rather than a single dict with different keys you can convert the defaultdict as follows:

>>> [{key: dict(value)} for key,value in B.iteritems()]
[{u'CI': {u'RP': 2}}, {u'JI': {u'RP': 1}}]
like image 56
Dave Webb Avatar answered Oct 01 '22 11:10

Dave Webb


Use the setdefault method of dict:

A = [{u'CI': {u'RP': 1}}, {u'CI': {u'RP': 1}},  {u'JI': {u'RP': 1}}]
B = {}
for i in A:
     k = i.keys()[0]             # k is 'CI' or 'JI' in this case
     B.setdefault(k, {u'RP': 0}) # set the default 'RP' to 0
     B[k]['RP'] += i[k][u'RP']   # add the RP. Because we already 
                                 # set the default to 0 this will not blow up
print B
# {u'CI': {u'RP': 2}, u'JI': {u'RP': 1}}
like image 33
Emil Ivanov Avatar answered Oct 01 '22 11:10

Emil Ivanov