例如,我有两个字典:
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}
也就是说:如果一个键在两个字典中都出现,则将它们的值相加,如果它只在一个字典中出现,则保留其值。
例如,我有两个字典:
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}
也就是说:如果一个键在两个字典中都出现,则将它们的值相加,如果它只在一个字典中出现,则保留其值。
当前回答
上述解决方案非常适合具有少量计数器的场景。如果你有一个很大的列表,像这样的就更好了:
from collections import Counter
A = Counter({'a':1, 'b':2, 'c':3})
B = Counter({'b':3, 'c':4, 'd':5})
C = Counter({'a': 5, 'e':3})
list_of_counts = [A, B, C]
total = sum(list_of_counts, Counter())
print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})
上述解决方案本质上是通过以下方法对计数器求和:
total = Counter()
for count in list_of_counts:
total += count
print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})
这个做的是同样的事情,但我认为它总是有助于看到它在下面有效地做了什么。
其他回答
使用集合。计数器:
>>> from collections import Counter
>>> A = Counter({'a':1, 'b':2, 'c':3})
>>> B = Counter({'b':3, 'c':4, 'd':5})
>>> A + B
Counter({'c': 7, 'b': 5, 'd': 5, 'a': 1})
计数器基本上是dict的一个子类,因此您仍然可以使用它们执行通常使用该类型执行的所有其他操作,例如遍历它们的键和值。
>>> A = {'a':1, 'b':2, 'c':3}
>>> B = {'b':3, 'c':4, 'd':5}
>>> c = {x: A.get(x, 0) + B.get(x, 0) for x in set(A).union(B)}
>>> print(c)
{'a': 1, 'c': 7, 'b': 5, 'd': 5}
myDict = {}
for k in itertools.chain(A.keys(), B.keys()):
myDict[k] = A.get(k, 0)+B.get(k, 0)
下面是另一个使用字典推导式结合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。
另外,请注意a.update(b)比a + b快2倍
from collections import Counter
a = Counter({'menu': 20, 'good': 15, 'happy': 10, 'bar': 5})
b = Counter({'menu': 1, 'good': 1, 'bar': 3})
%timeit a + b;
## 100000 loops, best of 3: 8.62 µs per loop
## The slowest run took 4.04 times longer than the fastest. This could mean that an intermediate result is being cached.
%timeit a.update(b)
## 100000 loops, best of 3: 4.51 µs per loop