Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python dict.add_by_value(dict_2)?

The problem:

>>> a = dict(a=1,b=2    )
>>> b = dict(    b=3,c=2)

>>> c = ???

c = {'a': 1, 'b': 5, 'c': 2}

So, the idea is two add to dictionaries by int/float values in the shortest form. Here's one solution that I've devised, but I don't like it, cause it's long:

c = dict([(i,a.get(i,0) + b.get(i,0)) for i in set(a.keys()+b.keys())])

I think there must be a shorter/concise solution (maybe something to do with reduce and operator module? itertools?)... Any ideas?


Update: I'm really hoping to find something more elegant like "reduce(operator.add, key = itemgetter(0), a+b)". (Obviously that isn't real code, but you should get the idea). But it seems that may be a dream.


Update: Still loking for more concise solutions. Maybe groupby can help? The solution I've come up with using "reduce"/"groupby" isn't actually concise:

from itertools import groupby
from operator import itemgetter,add

c = dict( [(i,reduce(add,map(itemgetter(1), v))) \
              for i,v in groupby(sorted(a.items()+b.items()), itemgetter(0))] )
like image 436
Slava V Avatar asked May 18 '09 11:05

Slava V


People also ask

How can I get a list of all keys in a dictionary?

Method 1: Get dictionary keys as a list using dict. The dict. keys() method in Python Dictionary, returns a view object that displays a list of all the keys in the dictionary in order of insertion.

What does dict keys () do in Python?

The methods dict. keys() and dict. values() return lists of the keys or values explicitly. There's also an items() which returns a list of (key, value) tuples, which is the most efficient way to examine all the key value data in the dictionary.

Is there == for dict in Python?

According to the python doc, you can indeed use the == operator on dictionaries.


2 Answers

Easiest to just use a Counter

>>> from collections import Counter
>>> a = dict(a=1,b=2    )
>>> b = dict(    b=3,c=2)
>>> Counter(a)+Counter(b)
Counter({'b': 5, 'c': 2, 'a': 1})
>>> dict(Counter({'b': 5, 'c': 2, 'a': 1}))
{'a': 1, 'c': 2, 'b': 5}
like image 94
John La Rooy Avatar answered Nov 04 '22 06:11

John La Rooy


solving not in terms of "length" but performance, I'd do the following:

>>> from collections import defaultdict
>>> def d_sum(a, b):
        d = defaultdict(int, a)
        for k, v in b.items():
            d[k] += v
        return dict(d)
>>> a = {'a': 1, 'b': 2}
>>> b = {'c': 2, 'b': 3}
>>> d_sum(a, b)
{'a': 1, 'c': 2, 'b': 5}

it's also py3k-compatible, unlike your original code.

like image 8
SilentGhost Avatar answered Nov 04 '22 05:11

SilentGhost