小编典典

如何合并字典的字典?

all

我需要合并多个字典,例如:

dict1 = {1:{"a":{A}}, 2:{"b":{B}}}

dict2 = {2:{"c":{C}}, 3:{"d":{D}}

A B CD成为树的叶子,就像{"info1":"value", "info2":"value2"}

字典的级别(深度)未知,可能是{2:{"c":{"z":{"y":{C}}}}}

在我的例子中,它代表一个目录/文件结构,节点是文档,叶子是文件。

我想合并它们以获得:

 dict3 = {1:{"a":{A}}, 2:{"b":{B},"c":{C}}, 3:{"d":{D}}}

我不确定如何使用 Python 轻松做到这一点。


阅读 71

收藏
2022-07-12

共1个答案

小编典典

这实际上非常棘手 - 特别是如果您在事情不一致时想要一个有用的错误消息,同时正确接受重复但一致的条目(这里没有其他答案可以做到......)

假设您没有大量条目,递归函数是最简单的:

def merge(a, b, path=None):
    "merges b into a"
    if path is None: 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]:
                pass # same leaf value
            else:
                raise Exception('Conflict at %s' % '.'.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 指出(如下)你可能有两个以上的字典,在这种情况下你可以使用:

reduce(merge, [dict1, dict2, dict3...])

一切都将被添加到dict1.

注意 :我编辑了我的初始答案以改变第一个参数;这使得“减少”更容易解释

PS :在python 3中,您还需要from functools import reduce

2022-07-12