python dict.add_by_value(dict_2)?

Sla*_*a V 9 python dictionary code-golf

问题:

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

>>> c = ???

c = {'a': 1, 'b': 5, 'c': 2}
Run Code Online (Sandbox Code Playgroud)

所以,这个想法是两个以最短的形式通过int/float值添加到字典.这是我设计的一个解决方案,但我不喜欢它,因为它很长:

c = dict([(i,a.get(i,0) + b.get(i,0)) for i in set(a.keys()+b.keys())])
Run Code Online (Sandbox Code Playgroud)

我认为必须有一个更短/更简洁的解决方案(可能与reduce和操作员模块有关吗?itertools?)...任何想法?


更新:我真的希望找到更优雅的东西,比如"reduce(operator.add,key = itemgetter(0),a + b)".(显然这不是真正的代码,但你应该得到这个想法).但似乎这可能是一个梦想.


更新:仍然需要更简洁的解决方案.也许groupby可以帮忙吗?我用"reduce"/"groupby"提出的解决方案实际上并不简洁:

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))] )
Run Code Online (Sandbox Code Playgroud)

Joh*_*ooy 9

最容易使用 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}
Run Code Online (Sandbox Code Playgroud)


Sil*_*ost 8

解决不是"长度"而是表现,我会做以下事情:

>>> 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}
Run Code Online (Sandbox Code Playgroud)

与原始代码不同,它也兼容py3k.


kcw*_*cwu 6

在我的第一印象中,我会写:

>>> c = a.copy()
>>> for k in b: c[k] = c.get(k, 0) + b[k]
Run Code Online (Sandbox Code Playgroud)


小智 5

如果你想要短代码,你就在那里.

如果你想要干净的代码,继承Ber defaultdict和过载__add__:

from collections import defaultdict

class summable(defaultdict):
    def __add__(self, rhs):
        new = summable()
        for i in (self.keys() + rhs.keys()):
            new[i] = self.get(i, 0) + rhs.get(i, 0)
        return new

a = summable(int, a=1, b=2)
b = summable(int, b=3, c=4)
c = a + b
print c
Run Code Online (Sandbox Code Playgroud)

得到:

>>> 
defaultdict(None, {'a': 1, 'c': 4, 'b': 5})
>>> 
Run Code Online (Sandbox Code Playgroud)


Ber*_*Ber 4

我认为一行代码已经很短了:)

如果你使用defaultdict并删除一些不必要的列表和集合创建,我可能会变成“半行” :

from collections import defaultdict

a = defaultdict(int, a=1, b=2)
b = defaultdict(int, b=3, c=4)

c = dict((k, a[k]+b[k]) for k in (a.keys() + b.keys()))
print c
Run Code Online (Sandbox Code Playgroud)