Cosnomi

プログラミングをする医学生。物を作ること、自動化すること、今まで知らなかったことを知ることが好き。TypeScript書いたり、Pythonで機械学習したりなど。

Twitter / GitHub / Keybase
TOP >

Pythonでネストされたdictにアクセスしたいが、存在しないときはNoneにしたいとき

Pythonにおいて辞書(dict)のvalueはdictを含むことができる。

例えば、first_dict['second'] = second_dictで、second_dict['mykey']の値を取りたいときは first_dict['second']['mykey'] とすればよい。しかし、これだと’second’というキーが存在しないときにエラーが起きる。(KeyError)

if 'second' not in first_dict.keys():
    return None
if 'mykey' not in first_dict['second'].keys():
    return None
return first_dict['second']['myKey']

とすればエラーは起きないが冗長なので、これと同じことをより簡潔な記述で実現したい。

tl;dr

first_dict.get('second', {}).get('mykey')

このようにすれば良い。

dict の get メソッド

dictの get メソッドはキーが存在しないときデフォルト値の None を返す。キーが存在するか分からないときに便利。

hoge = mydict.get('hogekey')

これで、hogeには’hogekey’というキーが存在するなら、その値(value)が入る。存在しないならNoneが入る。もちろん、 KeyError は発生しない。

デフォルト値はNone以外にすることも可能で、第二引数に入れた値が返ってくることになる。次の例では、キーが存在しないときは None ではなく 'default' が入ることになる。

hoge = mydict.get('hogekey', 'default')

get メソッドを重ねる

では、今回のネストされた辞書型(dict)のケースでは、単純にgetを2つ使えばよいのかというとそうもいかない。確かに KeyError は起きなくなるのだが、代わりに TypeError の可能性がある。

first_dict.get('second').get('mykey')

上の例では、first_dict'second' キーがあり、それがdictならばmykeyの存在にかかわらずエラーは起きない。しかし、'second'キーがない場合、None.get('mykey')となり、TypeError が発生する。

これを解決するには、デフォルト値を空dictにする

first_dict.get('second', {}).get('mykey')

secondキーが存在しないときは、空のdictを返すようにすると、{}にはもちろん 'mykey' は含まれていないので、{}.get('mykey')はNoneを返す。エラーは発生しない。

seconddictにmykeyが存在しないのと、そもそもseconddictが存在しないのを同一視したいときは便利だと思う。

ちなみに、最近の言語だと、 first.second?.third みたいな演算子がある。


最後まで読んでいただきありがとうございます。コメントフォームは設置していません。訂正・意見・感想などはTwitter(@cosnomi)などへお願いします。
記事一覧へ