1. ホーム
  2. パイソン

[解決済み】ネストした辞書の値を安全に取得する方法

2022-04-16 04:40:19

質問

ネストされた辞書があります。安全に値を取り出す方法は1つしかないのでしょうか?

try:
    example_dict['key1']['key2']
except KeyError:
    pass

あるいは、pythonに以下のようなメソッドがあるかもしれません。 get() ネストされた辞書のために?

どのように解決するのですか?

を使用することができます。 get を2回実行します。

example_dict.get('key1', {}).get('key2')

これは None のどちらかであれば key1 または key2 は存在しない。

を発生させる可能性があることに注意してください。 AttributeError もし example_dict['key1'] は存在するが、ディクト(またはディクトに似たオブジェクトで get メソッド) を使用します。また try..except が発生します。 TypeError の場合、代わりに example_dict['key1'] は添え字なしとする。

もう一つの違いは try...except は、最初のキーがなくなった直後に短絡してしまいます。の連鎖は get は呼び出されない。


構文を保持したい場合。 example_dict['key1']['key2'] が、KeyErrorsを発生させないようにするためには ハッシャーのレシピ :

class Hasher(dict):
    # https://stackoverflow.com/a/3405143/190597
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

example_dict = Hasher()
print(example_dict['key1'])
# {}
print(example_dict['key1']['key2'])
# {}
print(type(example_dict['key1']['key2']))
# <class '__main__.Hasher'>

キーがない場合、これは空のHasherを返すことに注意してください。

以来 Hasher のサブクラスです。 dict を使用するのと同じように、Hasher を使用することができます。 dict . 同じメソッドと構文が使えますが、ハッシャーは見つからないキーの扱いが異なるだけです。

通常の dictHasher このように

hasher = Hasher(example_dict)

を変換し Hasher を通常の dict を簡単に作成できます。

regular_dict = dict(hasher)


もう一つの方法は、ヘルパー関数で醜態を隠すことです。

def safeget(dct, *keys):
    for key in keys:
        try:
            dct = dct[key]
        except KeyError:
            return None
    return dct

そのため、残りのコードは比較的読みやすいままにしておくことができます。

safeget(example_dict, 'key1', 'key2')