On Mon, Mar 04, 2019 at 09:42:53AM -0500, David Mertz wrote:
On Mon, Mar 4, 2019, 8:30 AM Serhiy Storchaka <storchaka@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