例如,我有两个字典:

Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}

我需要一种python的方式来“组合”两个字典,这样的结果是:

{'a': 1, 'b': 5, 'c': 7, 'd': 5}

也就是说:如果一个键在两个字典中都出现,则将它们的值相加,如果它只在一个字典中出现,则保留其值。


当前回答

这个解决方案很容易使用,它被用作一个普通的字典,但你可以使用求和函数。

class SumDict(dict):
    def __add__(self, y):
        return {x: self.get(x, 0) + y.get(x, 0) for x in set(self).union(y)}

A = SumDict({'a': 1, 'c': 2})
B = SumDict({'b': 3, 'c': 4})  # Also works: B = {'b': 3, 'c': 4}
print(A + B)  # OUTPUT {'a': 1, 'b': 3, 'c': 6}

其他回答

要获得更通用和可扩展的方法,请检查mergedict。它使用singledispatch,并可以根据类型合并值。

例子:

from mergedict import MergeDict

class SumDict(MergeDict):
    @MergeDict.dispatch(int)
    def merge_int(this, other):
        return this + other

d2 = SumDict({'a': 1, 'b': 'one'})
d2.merge({'a':2, 'b': 'two'})

assert d2 == {'a': 3, 'b': 'two'}

没有额外进口的那个!

它们是一种python标准,叫做EAFP(请求原谅比请求许可更容易)。下面的代码基于该python标准。

# The A and B dictionaries
A = {'a': 1, 'b': 2, 'c': 3}
B = {'b': 3, 'c': 4, 'd': 5}

# The final dictionary. Will contain the final outputs.
newdict = {}

# Make sure every key of A and B get into the final dictionary 'newdict'.
newdict.update(A)
newdict.update(B)

# Iterate through each key of A.
for i in A.keys():

    # If same key exist on B, its values from A and B will add together and
    # get included in the final dictionary 'newdict'.
    try:
        addition = A[i] + B[i]
        newdict[i] = addition

    # If current key does not exist in dictionary B, it will give a KeyError,
    # catch it and continue looping.
    except KeyError:
        continue

编辑:感谢jerzyk提出的改进建议。

下面是另一个使用字典推导式结合dict()行为的选项:

dict3 = dict(dict1, **{ k: v + dict1.get(k, 0) for k, v in dict2.items() })
# {'a': 4, 'b': 2, 'c': 7, 'g': 1}

从https://docs.python.org/3/library/stdtypes.html dict类型:

https://docs.python.org/3/library/stdtypes.html#dict

如果给出了关键字参数,则关键字参数及其值将被添加到由位置参数创建的字典中。

词典理解

**{ k: v + dict1.get(v, 0), v in dict2.items() }

处理将dict1[1]添加到v.中。这里不需要显式if,因为dict1的默认值。Get可以设置为0。

dict1 = {'a':1, 'b':2, 'c':3}
dict2 = {'a':3, 'g':1, 'c':4}
dict3 = {} # will store new values

for x in dict1:
    
    if x in dict2: #sum values with same key
        dict3[x] = dict1[x] +dict2[x]
    else: #add the values from x to dict1
        dict3[x] = dict1[x]
        
#search for new values not in a
for x in dict2:
    if x not in dict1:
        dict3[x] = dict2[x]
print(dict3) # {'a': 4, 'b': 2, 'c': 7, 'g': 1}

一个更通用的解决方案,它也适用于非数字值:

a = {'a': 'foo', 'b':'bar', 'c': 'baz'}
b = {'a': 'spam', 'c':'ham', 'x': 'blah'}

r = dict(a.items() + b.items() +
    [(k, a[k] + b[k]) for k in set(b) & set(a)])

或者更普通一点:

def combine_dicts(a, b, op=operator.add):
    return dict(a.items() + b.items() +
        [(k, op(a[k], b[k])) for k in set(b) & set(a)])

例如:

>>> a = {'a': 2, 'b':3, 'c':4}
>>> b = {'a': 5, 'c':6, 'x':7}

>>> import operator
>>> print combine_dicts(a, b, operator.mul)
{'a': 10, 'x': 7, 'c': 24, 'b': 3}