Câu hỏi này đã cũ, nhưng tôi đã đến đây khi tìm kiếm một giải pháp "hợp nhất sâu". Các câu trả lời trên đã truyền cảm hứng cho những gì sau đây. Cuối cùng tôi đã tự viết vì có lỗi trong tất cả các phiên bản tôi đã thử nghiệm. Điểm quan trọng bị bỏ lỡ là, ở một số độ sâu tùy ý của hai ký tự đầu vào, đối với một số khóa, k, cây quyết định khi d [k] hoặc u [k] không là một lệnh sai.
Ngoài ra, giải pháp này không yêu cầu đệ quy, đối xứng hơn với cách thức dict.update()
hoạt động và trả về 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))