Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:合并两个任意数据结构_Python - Fatal编程技术网

Python:合并两个任意数据结构

Python:合并两个任意数据结构,python,Python,我希望高效地合并两个(相当任意的)数据结构:一个表示一组默认值,另一个表示覆盖。下面是示例数据。(天真地迭代结构是可行的,但速度非常慢。)关于处理此案例的最佳方法的想法 _默认值={'A':1122,'B':1133,'C':[9988,{'E':[{'F':6666,},],},],} _重写1={'B':1234,'C':[9876,{'D':2345,'E':[{'F':6789,'G':9876,},1357,],},},} _答案1={'A':1122,'B':1234,'C':[98

我希望高效地合并两个(相当任意的)数据结构:一个表示一组默认值,另一个表示覆盖。下面是示例数据。(天真地迭代结构是可行的,但速度非常慢。)关于处理此案例的最佳方法的想法

_默认值={'A':1122,'B':1133,'C':[9988,{'E':[{'F':6666,},],},],} _重写1={'B':1234,'C':[9876,{'D':2345,'E':[{'F':6789,'G':9876,},1357,],},},} _答案1={'A':1122,'B':1234,'C':[9876,{'D':2345,'E':[{'F':6789,'G':9876,},1357,],},],} _重写2={'C':[6543,{'E':[{'G':9876,},],},],} _答案2={'A':1122,'B':1133,'C':[6543,{'E':[{'F':6666,'G':9876,},],},],} _重写3={'B':3456,'C':[1357,{'D':4567,'E':[{'F':6677,'G':9876,},2468,],},},} _答案3={'A':1122,'B':3456,'C':[1357,{'D':4567,'E':[{'F':6677,'G':9876,},2468,],},],} 这是如何运行测试的示例: (字典更新不起作用,只是一个存根函数。)

进口itertools def MERGESTAFF(默认值,覆盖): #这不管用 结果=dict(默认值) 结果。更新(覆盖) 返回结果 def main(): 对于覆盖,请在itertools.izip中回答(\u覆盖,\u回答): 结果=合并内容(_默认值,覆盖) 打印('答案:%s'(答案)) 打印('结果:%s\n'(结果))
如果您知道一个结构总是另一个结构的子集,那么只需迭代超集,在O(n)时间内,您可以逐个元素检查它是否存在于子集中,如果不存在,则将其放在那里。据我所知,除了逐元素手动检查之外,没有什么神奇的方法可以做到这一点。正如我所说,这并不坏,因为它可以在O(n)复杂度下完成。

是您所需要的。但它会覆盖原始dict,因此,如果您想保留它,请复制原始dict。

您不能通过“迭代”来实现这一点,您将需要这样的递归例程:

def merge(a, b):
    if isinstance(a, dict) and isinstance(b, dict):
        d = dict(a)
        d.update({k: merge(a.get(k, None), b[k]) for k in b})
        return d

    if isinstance(a, list) and isinstance(b, list):
        return [merge(x, y) for x, y in itertools.izip_longest(a, b)]

    return a if b is None else b
如果你想让你的代码更快,不要疯狂地复制

您实际上不需要合并两个dict。你可以把它们锁起来

提供ChainMap类用于快速链接多个映射,以便将它们视为单个单元。它通常比创建新词典和运行多个update()调用快得多。

class ChainMap(UserDict.DictMixin):
"""Combine multiple mappings for sequential lookup"""

    def __init__(self, *maps):
        self._maps = maps

    def __getitem__(self, key):
        for mapping in self._maps:
            try:
                return mapping[key]
            except KeyError:
                pass
        raise KeyError(key)

def main():
    for override, answer in itertools.izip( _OVERRIDES, _ANSWERS ):
       result = ChainMap(override, _DEFAULT)

预期输出是什么?我认为答案是合并默认值和覆盖的预期结果。您可以显示您的“幼稚迭代”代码,尤其是您提到的代码。嵌套dict有什么问题?我不知道的另一个内置代码被选中了。但我怀疑这是否适用于嵌套的dict-假设
d={a:{x:1}}
o={a:{y:2}
,一个
d
o
的链图将返回
{x:1}
{code>{y:2}
{a
,但不是
{x:1,y:2}
@mpi:。这是ChainMap的一个缺点:它返回maps序列中的第一个有效映射。