在Python 2.7中合并多嵌套字典的最佳方法

mch*_*rnc 6 python merge dictionary python-2.7

我有两个嵌套的字典,我想将它们合并为一个(第二个字典覆盖第一个dict值).我看到了许多用于合并"扁平"(非嵌套)词典的漂亮解决方案,例如:

dict_result = dict1.copy()
dict_result.update(dict2)
Run Code Online (Sandbox Code Playgroud)

要么

dict_result = dict(dict1.items() + dict2.items())
Run Code Online (Sandbox Code Playgroud)

或(我最喜欢的)

dict_result = dict(d1,**d2)
Run Code Online (Sandbox Code Playgroud)

但找不到合并多嵌套dicts的最有效方法.

我试图避免递归.你的命题是什么?

tob*_*s_k 9

除非严格限制合并词典的深度,否则无法避免递归.1)此外,没有bultin或库函数可以做到这一点(也就是我所知道的没有),但实际上并不是那么难.这样的事情应该做:

def merge(d1, d2):
    for k in d2:
        if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
            merge(d1[k], d2[k])
        else:
            d1[k] = d2[k]   
Run Code Online (Sandbox Code Playgroud)

这里做的事情:它重复键中d2,如果钥匙也可以在发现d1无一不是字典,合并这些子字典,另有覆盖值d1与从d2.请注意,此更改d1及其子词典已就绪,因此您可能希望以前对其进行深层复制.

或使用此版本创建合并副本:

def merge_copy(d1, d2):
    return {k: merge_copy(d1[k], d2[k]) if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict) else d2[k] for k in d2}
Run Code Online (Sandbox Code Playgroud)

例:

>>> d1 = {"foo": {"bar": 23, "blub": 42}, "flub": 17}
>>> d2 = {"foo": {"bar": 100}, "flub": {"flub2": 10}, "more": {"stuff": 111}}
>>> merge(d1, d2)
>>> print d1
{'foo': {'bar': 100, 'blub': 42}, 'flub': {'flub2': 10}, 'more': {'stuff': 111}}
Run Code Online (Sandbox Code Playgroud)

1)可以使用堆栈进行迭代,但这只会使事情变得更复杂,并且应该只是为了避免最大递归深度的问题.