我正在寻找一种在不覆盖 levelA 的情况下使用 dict update 的内容更新 dict dictionary1 的方法
dictionary1={'level1':{'level2':{'levelA':0,'levelB':1}}}
update={'level1':{'level2':{'levelB':10}}}
dictionary1.update(update)
print dictionary1
{'level1': {'level2': {'levelB': 10}}}
我知道 update 会删除 level2 中的值,因为它正在更新最低的键 level1。
鉴于 dictionary1 和 update 可以有任意长度,我该如何解决这个问题?
最佳答案
@FM 的回答有正确的总体思路,即递归解决方案,但有些特殊的编码和至少一个错误。我建议改为:
Python 2:
import collections
def update(d, u):
for k, v in u.iteritems():
if isinstance(v, collections.Mapping):
d[k] = update(d.get(k, {}), v)
else:
d[k] = v
return d
Python 3:
import collections.abc
def update(d, u):
for k, v in u.items():
if isinstance(v, collections.abc.Mapping):
d[k] = update(d.get(k, {}), v)
else:
d[k] = v
return d
当“更新”有一个 k
, v
项目时,错误就会出现,其中 v
是一个 dict
和 k
最初不是正在更新的字典中的键 - @FM 的代码“跳过”这部分更新(因为它在一个空的新 dict
上执行它它不会保存或返回任何地方,只是在递归调用返回时丢失)。
我的其他更改很小:当 .get
更快、更清晰地完成相同的工作时,没有理由使用 if
/else
构造, 而 isinstance
最好应用于抽象基类(而不是具体基类)以实现通用性。
https://stackoverflow.com/questions/3232943/