我正在寻找一种Pythonic的方式(尽可能少的代码)来合并两个字典的内容:
basket1 = {"ham":2,"eggs":3}
basket2 = {"eggs":4,"spam":1}
我希望获得第三个篮子,它将是另外两个篮子的“总和”,篮子3应该是:
basket3 --> {"ham":2,"eggs":7,"spam":1}
如果可能的话,可以使用 set
来完成此操作。
我正在寻找一种Pythonic的方式(尽可能少的代码)来合并两个字典的内容:
basket1 = {"ham":2,"eggs":3}
basket2 = {"eggs":4,"spam":1}
basket3 --> {"ham":2,"eggs":7,"spam":1}
如果可能的话,可以使用 set
来完成此操作。
我会使用一个Counter
,它是一种带有一些不错特性的defaultdict
:
>>> from collections import Counter
>>> basket1 = {"ham":2,"eggs":3}
>>> basket2 = {"eggs":4,"spam":1}
>>> basket_sum = Counter(basket1) + Counter(basket2)
>>> basket_sum
Counter({'eggs': 7, 'ham': 2, 'spam': 1})
如果需要,您可以将其转换回纯 dict
:
>>> dict(basket_sum)
{'eggs': 7, 'ham': 2, 'spam': 1}
由于您正在尝试计算值,请使用collections.Counter
:
basket3 = collections.Counter(basket1)
basket3.update(basket2)
或者:
basket3 = collections.Counter(basket1) + collections.Counter(basket2)
update
方法。知道 update
对于 Counter
类型的字典有不同的行为是很有用的。 - Akavallcount
是Food
的成员吗?不,如果是这样,你需要做一些不同的事情。你可以始终创建两个Counter({food: quantity for food in foods})
对象,将它们相加,然后在事后转换回列表。但此时,手动创建两个set
可能更简单,或者向Food
添加一个update
方法,或者... - abarnertIn [2]: basket1 = {"ham":2,"eggs":3}
In [3]: basket2 = {"eggs":4,"spam":1}
In [4]: baskets = [basket1, basket2]
In [5]: answer = collections.defaultdict(int)
In [6]: for basket in baskets:
...: for item in basket:
...: answer[item] += basket[item]
...:
In [7]: answer
Out[7]: defaultdict(<type 'int'>, {'eggs': 7, 'ham': 2, 'spam': 1})
In [8]: dict(answer)
Out[8]: {'eggs': 7, 'ham': 2, 'spam': 1}
answer[item] += 1
更改为 answer[item] += basket[item]
来修复这个问题。 - DSM
Food
实例列表转换为字典,例如def basket_to_dict(basket): return {f.name: f.quantity for f in basket}
,那么类似于[Food(n,q) for n,q in (Counter(basket_to_dict(b1)) + Counter(basket_to_dict(b2))).iteritems()]
这样的代码就可以工作了。(Python >= 2.7.) - DSM