更新不同深度的嵌套字典的值我正在寻找一种方法来更新dict dictionary1与dict更新的内容wihout覆盖levelAdictionary1={'level1':{'level2':{'levelA':0,'levelB':1}}}update={'level1':{'level2':{'levelB':10}}}dictionary1.update(update)print dictionary1{'level1': {'level2': {'levelB': 10}}}我知道更新会删除level2中的值,因为它正在更新最低密钥level1。鉴于dictionary1和update可以有任何长度,我怎么能解决这个问题呢?
3 回答

浮云间
TA贡献1829条经验 获得超4个赞
即递归解决方案,但有些特殊的编码和至少一个bug。我推荐,相反:
import collectionsimport six# python 3.8+ compatibilitytry: collectionsAbc = collections.abcexcept: collectionsAbc = collectionsdef update(d, u): for k, v in six.iteritems(u): dv = d.get(k, {}) if not isinstance(dv, collectionsAbc.Mapping): d[k] = v elif isinstance(v, collectionsAbc.Mapping): d[k] = update(dv, v) else: d[k] = v return d
该错误时显示“更新”有k
,v
项目在那里v
是dict
和k
最初不是被更新在字典中的关键- @ FM代码“跳过”更新的这一部分(因为它执行它的新的空dict
其没有保存或返回任何地方,只是在递归调用返回时丢失)。
我的其他更改是次要的:没有理由if
/ else
construct什么时候.get
同一个工作更快更干净,并且isinstance
最好应用于抽象基类(不是具体的)以获得通用性。

慕婉清6462132
TA贡献1804条经验 获得超2个赞
对我说了一点,但多亏了@ Alex的帖子,他填补了我所缺少的空白。但是,如果递归中的值dict
恰好是a ,我遇到了一个问题list
,所以我想我会分享,并扩展他的答案。
import collectionsdef update(orig_dict, new_dict): for key, val in new_dict.iteritems(): if isinstance(val, collections.Mapping): tmp = update(orig_dict.get(key, { }), val) orig_dict[key] = tmp elif isinstance(val, list): orig_dict[key] = (orig_dict.get(key, []) + val) else: orig_dict[key] = new_dict[key] return orig_dict

偶然的你
TA贡献1841条经验 获得超3个赞
当用字典替换整数等元素时不起作用,例如update({'foo':0},{'foo':{'bar':1}})
。此更新解决了它:
import collectionsdef update(d, u): for k, v in u.iteritems(): if isinstance(d, collections.Mapping): if isinstance(v, collections.Mapping): r = update(d.get(k, {}), v) d[k] = r else: d[k] = u[k] else: d = {k: u[k]} return d update({'k1': 1}, {'k1': {'k2': {'k3': 3}}})
添加回答
举报
0/150
提交
取消