Pertanyaan ini sudah lama, tetapi saya mendarat di sini ketika mencari solusi "penggabungan yang mendalam". Jawaban di atas mengilhami apa yang berikut. Saya akhirnya menulis sendiri karena ada bug di semua versi yang saya uji. Titik kritis yang terlewatkan adalah, pada kedalaman sewenang-wenang dari dua dicts input, untuk beberapa kunci, k, pohon keputusan ketika d [k] atau u [k] bukan dict yang salah.
Juga, solusi ini tidak memerlukan rekursi, yang lebih simetris dengan cara dict.update()
kerjanya, dan kembali 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))