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':[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'(结果))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
如果您知道一个结构总是另一个结构的子集,那么只需迭代超集,在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)
d={a:{x:1}}
和o={a:{y:2}
,一个d
和o
的链图将返回{x:1}
或{code>{y:2}
键{a
,但不是{x:1,y:2}
@mpi:。这是ChainMap的一个缺点:它返回maps序列中的第一个有效映射。