[Python-ideas] Dict joining using + and +=
Steven D'Aprano
steve at pearwood.info
Mon Mar 4 11:44:09 EST 2019
On Mon, Mar 04, 2019 at 09:42:53AM -0500, David Mertz wrote:
> On Mon, Mar 4, 2019, 8:30 AM Serhiy Storchaka <storchaka at gmail.com> wrote:
>
> > But is merging two dicts a common enough problem that needs introducing
> > an operator to solve it? I need to merge dicts maybe not more than one
> > or two times by year, and I am fine with using the update() method.
> > Perhaps {**d1, **d2} can be more appropriate in some cases, but I did not
> > encounter such cases yet.
> >
>
> Like other folks in the thread, I also want to merge dicts three times per
> year.
I'm impressed that you have counted it with that level of accuracy. Is
it on the same three days each year, or do they move about? *wink*
> And every one of those times, itertools.ChainMap is the right way to
> do that non-destructively, and without copying.
Can you elaborate on why ChainMap is the right way to merge multiple
dicts into a single, new dict?
ChainMap also seems to implement the opposite behaviour to that usually
desired: first value seen wins, instead of last:
py> from collections import ChainMap
py> cm = ChainMap({'a': 1}, {'b': 2}, {'a': 999})
py> cm
ChainMap({'a': 1}, {'b': 2}, {'a': 999})
py> dict(cm)
{'a': 1, 'b': 2}
If you know ahead of time which order you want, you can simply reverse
it:
# prefs = site_defaults + user_defaults + document_prefs
prefs = dict(ChainMap(document_prefs, user_defaults, site_defaults))
but that seems a little awkward to me, and reads backwards. I'm used to
thinking reading left-to-right, not right-to-left.
ChainMap seems, to me, to be ideal for implementing "first wins"
mappings, such as emulating nested scopes, but not so ideal for
update/merge operations.
--
Steven
More information about the Python-ideas
mailing list