How to make a copy of chained dicts effectively and nicely?

Jussi Piitulainen jussi.piitulainen at helsinki.fi
Tue Sep 27 03:32:06 EDT 2016


Nagy László Zsolt writes:

> The result that I need should be a real dict, not just a ChainMap. (It
> is because I have to mutate it.)
>
> d1 = {'a':1, 'b':2}
> d2 = {'c':3, 'd':4}
> d3 = {'e':5, 'f':6}
>
> #1. My first naive approach was:
>
>
> from collections import ChainMap
> d = {}
> for key,value in ChainMap(d1, d2, d3).items():
>     d[key] = value
>
> #2. Much more effective version, but requires too many lines:
>
> d= {}
> d.update(d1)
> d.update(d2)
> d.update(d3)
>
> #3. Third version is more compact. It uses a side effect inside a list
> comp., so I don't like it either:
>
> d = {}
> [d.update(_) for _ in [d1, d2, d3]]

That really should be just a loop:

d = {}
for _ in (d1, d2, d3):
    d.update(_)

> #4. Last version:
>
> d = {}
> d.update(ChainMap(d1, d2, d3))
>
> Visually, it is the cleanest and the easiest to understand. However, it
> uses ChainMap.__iter__ and that goes over all mappings in a loop written
> in pure Python.
>
> Is there a version that is as effective as #3, but as clean and nice
> as #4?

Maybe see above.

Or consider also this, which looks straightforward to me:

d = { k:v for d in (d1, d2, d3) for k,v in d.items() }

Is ChainMap really that bad? Otherwise the following would look somewhat
nice:

d = dict(ChainMap(d1, d2, d3).items())

Those come to mind.



More information about the Python-list mailing list