简体   繁体   English

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

[英]The best way to merge multi-nested dictionaries in Python 2.7

I have two nested dictionaries and I want to merge them into one (where second dict overrides first dict values). 我有两个嵌套的字典,我想将它们合并为一个(第二个字典覆盖第一个dict值)。 I saw a lot of beautiful solutions for merging "flat" (not nested) dictionaries, eg: 我看到了许多用于合并“扁平”(非嵌套)词典的漂亮解决方案,例如:

dict_result = dict1.copy()
dict_result.update(dict2)

or 要么

dict_result = dict(dict1.items() + dict2.items())

or (my favorit one) 或(我最喜欢的)

dict_result = dict(d1,**d2)

but couldn't find the most efficient way to merge multi-nested dicts. 但找不到合并多嵌套dicts的最有效方法。

I'm trying to avoid recursion. 我试图避免递归。 What is your proposition? 你的命题是什么?

Unless the depth of the dictionaries to merge is strictly limited, there's no way to avoid recursion. 除非严格限制合并词典的深度,否则无法避免递归。 1) Also, there's no bultin or library function to do this (that is, none that I know of), but it's actually not all that hard. 1)此外,没有bultin或库函数可以做到这一点(也就是我所知道的没有),但实际上并不是那么难。 Something like this should do: 这样的事情应该做:

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]   

What this does: It iterates the keys in d2 and if the key can also be found in d1 and both are dictionaries, merge those sub-dictionaries, otherwise overwrite the value in d1 with that from d2 . 这样做:它迭代d2的键,如果键也可以在d1找到并且都是字典,则合并这些子字典,否则用d2的值覆盖d1的值。 Note that this changes d1 and its sub-dictionaries in place , so you might want to deep-copy it before. 注意这改变d1和它子词典,所以你可能要到前深复制。

Or use this version to create a merged copy: 或使用此版本创建合并副本:

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}

Example: 例:

>>> 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}}

1) You can make it iterative, using a stack, but this will only make things more complicated and should only be done to avoid problems with maximum recursive depth. 1)可以使用堆栈进行迭代,但这只会使事情变得更复杂,并且应该只是为了避免最大递归深度的问题。

Modified version of the above merge_copy function for dicts that can be thought of as merging parent and child where you want the parent to inherit all the values from child to create a new dict. 用于merge_copy的上述merge_copy函数的修改版本可以被认为是合并父级和子级,您希望父级继承子级的所有值以创建新的dict。

def merge_copy(child, parent):
    '''returns parent updated with child values if exists'''
    d = {}
    for k in parent:
        if k in child and isinstance(child[k], dict) and isinstance(parent[k], dict):
            v = merge_copy(child[k], parent[k])
        elif k in child:
            v = child[k]
        else:
            v = parent[k]
        d[k] = v
    return d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM