除非合并的字典深度严格限制,否则无法避免递归。1)此外,没有内置或库函数可以做到这一点(也就是说,我不知道任何一个),但实际上并不难。像这样的东西应该可以:
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]
这段代码的作用是:遍历d2
中的键,如果该键也可以在d1
中找到并且两个键都是字典,则合并这些子字典,否则用d2
中的值覆盖d1
中的值。请注意,这将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}
例子:
>>> 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)你可以使用栈来实现迭代,但这只会使事情变得更加复杂,并且只应该用于避免递归深度过大的问题。
dict(itertools.chain(dict1.iteritems(), dict2.iteritems()))
可以避免这种情况。当然,在90%的情况下,您甚至不需要一个新字典,使用ChainMap
会更简单和更有效...但无论如何,这都与您的问题无关。 - abarnert