python - 更新不同深度的嵌套字典的值

我正在寻找一种在不覆盖 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 是一个 dictk 最初不是正在更新的字典中的键 - @FM 的代码“跳过”这部分更新(因为它在一个空的新 dict 上执行它它不会保存或返回任何地方,只是在递归调用返回时丢失)。

我的其他更改很小:当 .get 更快、更清晰地完成相同的工作时,没有理由使用 if/else 构造, 而 isinstance 最好应用于抽象基类(而不是具体基类)以实现通用性。

https://stackoverflow.com/questions/3232943/

相关文章:

python - 如何查看安装了哪个版本的nltk、scikit learn?

c - 如何在 C 中使用/dev/random 或 urandom?

Python 风格 - 用字符串续行?

python - 在 localhost 上,我如何选择一个空闲端口号?

python - 为什么字典和集合中的顺序是任意的?

python - Jinja2 简写条件

python - 了解python的主要方法

linux - linux命令末尾的 "&"是什么意思?

python - Django admin 中同一模型的多个 ModelAdmins/ View

linux - 如何连接两个字符串以构建完整路径