这实际上非常棘手 - 特别是如果您想要在事情不一致时收到有用的错误消息,同时正确接受重复但一致的条目(这里没有其他答案可以做到这一点......)
假设您没有大量条目,递归函数是最简单的:
def merge(a: dict, b: dict, path=[]):
for key in b:
if key in a:
if isinstance(a[key], dict) and isinstance(b[key], dict):
merge(a[key], b[key], path + [str(key)])
elif a[key] != b[key]:
raise Exception('Conflict at ' + '.'.join(path + [str(key)]))
else:
a[key] = b[key]
return a
# works
print(merge({1:{"a":"A"},2:{"b":"B"}}, {2:{"c":"C"},3:{"d":"D"}}))
# has conflict
merge({1:{"a":"A"},2:{"b":"B"}}, {1:{"a":"A"},2:{"b":"C"}})
请注意,这会发生突变a
- 的内容b
被添加到a
(也被返回)。如果你想保留a
你可以这样称呼它merge(dict(a), b)
.
agf 指出(如下)你可能有两个以上的字典,在这种情况下你可以使用:
from functools import reduce
reduce(merge, [dict1, dict2, dict3...])
一切都将被添加到dict1
.
Note:我编辑了最初的答案以改变第一个参数;这使得“减少”更容易解释