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 ma propre solution car il y avait des bogues 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 certaine clé, k, l'arbre de décision lorsque d[k] ou u[k] est pas une dictée était défectueuse.
De plus, cette solution ne nécessite pas de récursion, ce qui est plus symétrique avec la façon dont les dict.update()
fonctionne, et renvoie 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
if k not in d:
# add new key into d
d[k] = v
elif not isinstance(d[k], 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((d[k], v))
0 votes
L'imbrication est-elle toujours de trois niveaux de profondeur ou peut-on avoir une imbrication d'une profondeur arbitraire ?
1 votes
Il peut avoir n'importe quelle profondeur/longueur.
0 votes
Corrigez-moi si je me trompe, mais il semble que la solution idéale ici nécessite la mise en œuvre du modèle de conception composite.