さまざまな深さのネストされた辞書の値を更新する 質問する

さまざまな深さのネストされた辞書の値を更新する 質問する

上書きせずにdictdictionary1の内容を更新する方法を探していますupdatelevelA

dictionary1 = {
    "level1": {
        "level2": {"levelA": 0, "levelB": 1}
    }
}
update = {
    "level1": {
        "level2": {"levelB": 10}
    }
}
dictionary1.update(update)
print(dictionary1)
{
    "level1": {
        "level2": {"levelB": 10}
    }
}

更新によって、最も低いキーであるレベル 1 が更新されるため、レベル 2 の値が削除されることはわかっています。

dictionary1 と update の長さは任意である可能性があるので、この問題にどのように対処すればよいでしょうか?

ベストアンサー1

@FM の回答は、再帰的な解決策など、一般的な考え方は正しいのですが、コーディングがやや特殊で、バグが少なくとも 1 つあります。代わりに、次の方法をお勧めします。

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

Python3:

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、がであり、更新される辞書内の元々のキーではない場合に発生します -- @FM のコードは更新のこの部分を「スキップ」します (空の new に対して実行するので、どこにも保存または返されず、再帰呼び出しが返されるときに失われるだけです)。vvdictkdict

その他の変更は軽微です。/構造が同じ処理をより高速かつクリーンに実行し、汎用性のために抽象基本クラス (具象クラスではない) に適用するのに最適な場合、 if/構造を使用する理由はありません。else.getisinstance

おすすめ記事