12/5/2018, 8:15 PM GMT+9

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

tl;dr

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

仕組みを詳しく説明します。

何がしたいか

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']

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

dict の get メソッド

dict の get メソッドはキーが存在しないときデフォルト値の None を返す。だから、mydict に’hogekey’というキーが存在するかわからないときは、

hoge = mydict.get('hogekey')

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

デフォルト値は None 以外にすることも可能で、

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

とすれば、存在しないときは None ではなく'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が存在しないのを同一視したいときは便利だと思う。


Cosnomi
Cosnomi

コンピュータ(Web, 機械学習など)が好きな医学部生

Twitter / GitHub