For dictionaries x
and y
, z
becomes a shallowly merged-merged dictionary with values from y
replacing those from x
.
In Python 3.9.0 or greater (released 17 October 2020): PEP-584, discussed here, was implemented and provides the simplest method:
z = x | y # NOTE: 3.9+ ONLY
In Python 3.5 or greater:
z = {**x, **y}
In Python 2, (or 3.4 or lower) write a function:
def merge_two_dicts(x, y):
z = x.copy() # start with x's keys and values of x
z.update(y) # modifies z with y's keys and values & returnsof Noney
return z
and now:
z = merge_two_dicts(x, y)
Say you have two dictionaries and you want to merge them into a new dictdictionary without altering the original dictionaries:
It is now showing as implemented in the release schedule for 3.5, PEP 478, and it has now made its way into the What's New in Python 3.5 document.
In both approaches, y
will come second and its values will replace x
's values, thus 'b'b
will point to 3
in our final result.
You can also make a function to merge an undefinedarbitrary number of dictionaries, from zero to a very large number:
Here's an example where yy
should have precedence, but instead the value from xx
is retained due to the arbitrary order of sets:
This uses the dict
constructor and is very fast and memory-efficient (even slightly more-so so than our two-step process) but unless you know precisely what is happening here (that is, the second dict is being passed as keyword arguments to the dict constructor), it's difficult to read, it's not the intended usage, and so it is not Pythonic.
Dictionaries are intended to take hashable keys (e.g. frozensetsfrozenset
s or tuples), but this method fails in Python 3 when keys are not strings.
Again, it doesn't work for 3 when keys are non-stringsnot strings. The implicit calling contract is that namespaces take ordinary dictionaries, while users must only pass keyword arguments that are strings. All other callables enforced it. dict
broke this consistency in Python 2:
This inconsistency was bad given other implementations of Python (PypyPyPy, Jython, IronPython). Thus it was fixed in Python 3, as this usage could be a breaking change.
or in pythonPython 2.6 (and perhaps as early as 2.4 when generator expressions were introduced):