Skip to content

Instantly share code, notes, and snippets.

@rhoboro
Created November 22, 2017 00:18
Show Gist options
  • Save rhoboro/58b9ef02455b30b8364df8815169ce87 to your computer and use it in GitHub Desktop.
Save rhoboro/58b9ef02455b30b8364df8815169ce87 to your computer and use it in GitHub Desktop.
dict.get()の多次元版
from collections import abc
def get_from_nested(dic, keys=None, default=None):
"""
>>> get_from_nested({'hoge': {'fuga': 1}}, keys=['hoge'], default=[])
{'fuga': 1}
>>> get_from_nested({'hoge': {'fuga': 1}}, keys=['hoge', 'fuga'], default=[])
1
>>> get_from_nested({'hoge': {'fuga': 1}}, keys=['hoge', 'fuga', 'yeah'], default=[])
[]
>>> get_from_nested({}, keys=['hoge', 'fuga', 'yeah'], default=[])
[]
>>> get_from_nested({'hoge': {'fuga': 1}}, keys=[])
>>> get_from_nested({'hoge': {'fuga': 1}})
"""
keys = keys or []
if keys:
head, *tail = list(keys)
value = dic.get(head, default)
if isinstance(value, abc.Mapping) and tail:
return get_from_nested(value, tail, default=default)
elif tail:
# キーは続いてるけどすでに値が見つかってる
return default
else:
return value
else:
return default
if __name__=='__main__':
import doctest
doctest.testmod()
@rhoboro
Copy link
Author

rhoboro commented Nov 22, 2017

最後のelseを外してreturnのインデントあげても動くし、elifも return default if tail else value でなくせるけど、このままが見やすいかなぁというところ。
もっといい書き方あったらコメントください。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment