我希望有效地合并两个(相当任意的)数据结构:一个表示一组默认值,另一个表示覆盖.以下示例数据. (天真地对结构进行迭代工作,但速度非常慢.)关于处理此案例的最佳方法的想法?
_DEFAULT = { 'A': 1122, 'B': 1133, 'C': [ 9988, { 'E': [ { 'F': 6666, }, ], }, ], } _OVERRIDE1 = { 'B': 1234, 'C': [ 9876, { 'D': 2345, 'E': [ { 'F': 6789, 'G': 9876, }, 1357, ], }, ], } _ANSWER1 = { 'A': 1122, 'B': 1234, 'C': [ 9876, { 'D': 2345, 'E': [ { 'F': 6789, 'G': 9876, }, 1357, ], }, ], } _OVERRIDE2 = { 'C': [ 6543, { 'E': [ { 'G': 9876, }, ], }, ], } _ANSWER2 = { 'A': 1122, 'B': 1133, 'C': [ 6543, { 'E': [ { 'F': 6666, 'G': 9876, }, ], }, ], } _OVERRIDE3 = { 'B': 3456, 'C': [ 1357, { 'D': 4567, 'E': [ { 'F': 6677, 'G': 9876, }, 2468, ], }, ], } _ANSWER3 = { 'A': 1122, 'B': 3456, 'C': [ 1357, { 'D': 4567, 'E': [ { 'F': 6677, 'G': 9876, }, 2468, ], }, ], }
这是如何运行测试的示例:
(字典更新不起作用,只是一个存根函数.)
import itertools def mergeStuff( default, override ): # This doesn't work result = dict( default ) result.update( override ) return result def main(): for override, answer in itertools.izip( _OVERRIDES, _ANSWERS ): result = mergeStuff(_DEFAULT, override) print('ANSWER: %s' % (answer) ) print('RESULT: %s\n' % (result) )
最佳答案 你不能通过“迭代”来做到这一点,你需要一个像这样的递归例程:
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