Cette question est ancienne, mais j'ai atterri ici en cherchant une solution de "fusion profonde". Les réponses ci-dessus ont inspiré ce qui suit. J'ai fini par écrire le mien car il y avait des bugs dans toutes les versions que j'ai testées. Le point critique manqué était, à une certaine profondeur arbitraire des deux dicts d'entrée, pour une clé, k, l'arbre de décision lorsque d [k] ou u [k] n'est pas un dict était défectueux.
En outre, cette solution ne nécessite pas de récursivité, qui est plus symétrique avec la façon dont dict.update()fonctionne et retourne None.
import collections
def deep_merge(d, u):
"""Do a deep merge of one dict into another.
This will update d with values in u, but will not delete keys in d
not found in u at some arbitrary depth of d. That is, u is deeply
merged into d.
Args -
d, u: dicts
Note: this is destructive to d, but not u.
Returns: None
"""
stack = [(d,u)]
while stack:
d,u = stack.pop(0)
for k,v in u.items():
if not isinstance(v, collections.Mapping):
# u[k] is not a dict, nothing to merge, so just set it,
# regardless if d[k] *was* a dict
d[k] = v
else:
# note: u[k] is a dict
# get d[k], defaulting to a dict, if it doesn't previously
# exist
dv = d.setdefault(k, {})
if not isinstance(dv, collections.Mapping):
# d[k] is not a dict, so just set it to u[k],
# overriding whatever it was
d[k] = v
else:
# both d[k] and u[k] are dicts, push them on the stack
# to merge
stack.append((dv, v))