Dict merge in a dict comprehension

柔情痞子 提交于 2019-12-03 15:27:52

问题


In python 3.5, we can merge dicts by using double-splat unpacking

>>> d1 = {1: 'one', 2: 'two'}
>>> d2 = {3: 'three'}
>>> {**d1, **d2}
{1: 'one', 2: 'two', 3: 'three'}

Cool. It doesn't seem to generalise to dynamic use cases, though:

>>> ds = [d1, d2]
>>> {**d for d in ds}
SyntaxError: dict unpacking cannot be used in dict comprehension

Instead we have to do reduce(lambda x,y: {**x, **y}, ds, {}), which seems a lot uglier. Why the "one obvious way to do it" is not allowed by the parser, when there doesn't seem to be any ambiguity in that expression?


回答1:


It's not exactly an answer to your question but I'd consider using ChainMap to be an idiomatic and elegant way to do what you propose (merging dictionaries in-line):

>>> d1 = {1: 'one', 2: 'two'}
>>> d2 = {3: 'three'}
>>> ds = [d1, d2]
>>> dict(ChainMap(*ds))
{1: 'one', 2: 'two', 3: 'three'}

Although it's not a particularly transparent solution, since many programmers might not know exactly how a ChainMap works. Note that (as @AnttiHaapala points out) "first found is used" so, depending on your intentions you might need to make a call to reversed before passing your dicts into 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'}



回答2:


To me, the obvious way is:

d_out = {}
for d in ds:
    d_out.update(d)

This is quick and probably quite performant. I don't know that I can speak for the python developers, but I don't know that your expected version is more easy to read. For example, your comprehension looks more like a set-comprehension to me due to the lack of a :. FWIW, I don't think there is any technical reason (e.g. parser ambiguity) that they couldn't add that form of comprehension unpacking.

Apparently, these forms were proposed, but didn't have universal enough support to warrant implementing them (yet).




回答3:


final = {}
for data in [d1, d2]:
    final = {**final,**data}


来源:https://stackoverflow.com/questions/37584544/dict-merge-in-a-dict-comprehension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!