在python 3.5中,我们可以通过使用双splat解包来合并dicts
>>> d1 = {1: 'one', 2: 'two'}
>>> d2 = {3: 'three'}
>>> {**d1, **d2}
{1: 'one', 2: 'two', 3: 'three'}
冷却。但它似乎并未概括为动态用例:
>>> ds = [d1, d2]
>>> {**d for d in ds}
SyntaxError: dict unpacking cannot be used in dict comprehension
相反,我们必须做reduce(lambda x,y: {**x, **y}, ds, {})
,这似乎更加丑陋。为什么解析器不允许“一种明显的方法”,当表达式中似乎没有任何歧义时?
答案 0 :(得分:11)
这不完全是你问题的答案,但我考虑使用ChainMap
作为一种惯用而优雅的方式来做你的建议(合并字典在线):
>>> d1 = {1: 'one', 2: 'two'}
>>> d2 = {3: 'three'}
>>> ds = [d1, d2]
>>> dict(ChainMap(*ds))
{1: 'one', 2: 'two', 3: 'three'}
虽然它不是一个特别透明的解决方案,但由于许多程序员可能不确切知道ChainMap
的工作原理。请注意(正如@AnttiHaapala指出的那样)"首先使用"因此,根据您的意图,您可能需要先致电reversed
,然后再将dict
传递给ChainMap
。
>>> d2 = {3: 'three', 2:'LOL'}
>>> dict(ChainMap(*ds))
{1: 'one', 2: 'two', 3: 'three'}
>>> dict(ChainMap(*reversed(ds)))
{1: 'one', 2: 'LOL', 3: 'three'}
答案 1 :(得分:6)
对我来说,显而易见的方法是:
-Wconversion
这很快,可能非常有效。我不知道我可以代表python开发人员,但我不知道你期望的版本更容易阅读。例如,由于缺少d_out = {}
for d in ds:
d_out.update(d)
,你的理解看起来更像是对我的理解。 FWIW,我认为没有任何技术原因(例如解析器含糊不清),他们无法添加这种形式的理解解包。
显然,these forms were proposed,但没有足够普遍的支持来保证实施它们(还有)。
答案 2 :(得分:0)
final = {}
for data in [d1, d2]:
final = {**final,**data}
答案 3 :(得分:0)
您可以定义此功能:
from collections import ChainMap
def mergeDicts(l):
return dict(ChainMap(*reversed(list(l))))
然后您可以像这样使用它:
>>> d1 = {1: 'one', 2: 'two'}
>>> d2 = {3: 'three'}
>>> ds = [d1, d2]
>>> mergeDicts(ds)
{1: 'one', 2: 'two', 3: 'three'}
答案 4 :(得分:0)
您可以使用itertools.chain
或itertools.chain.from_iterable
:
import itertools
ds = [{'a': 1, 'b': 2}, {'c': 30, 'b': 40}]
merged_d = dict(itertools.chain(*(d.items() for d in ds)))
print(merged_d) # {'a': 1, 'b': 40, 'c': 30}