我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
try:
example_dict['key1']['key2']
except KeyError:
pass
或者python有一个类似get()的方法用于嵌套字典?
我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
try:
example_dict['key1']['key2']
except KeyError:
pass
或者python有一个类似get()的方法用于嵌套字典?
当前回答
下面是一个基于unutbu函数答案的解决方案:
Python命名指南 默认值作为参数 不用try,只是检查key是否在object上
def safe_get(dictionary, *keys, default=None):
for key in keys:
if key not in dictionary:
return default
dictionary = dictionary[key]
return dictionary
其他回答
我的实现下降到子字典,忽略None值,但失败与TypeError如果发现任何其他
def deep_get(d: dict, *keys, default=None):
""" Safely get a nested value from a dict
Example:
config = {'device': None}
deep_get(config, 'device', 'settings', 'light')
# -> None
Example:
config = {'device': True}
deep_get(config, 'device', 'settings', 'light')
# -> TypeError
Example:
config = {'device': {'settings': {'light': 'bright'}}}
deep_get(config, 'device', 'settings', 'light')
# -> 'light'
Note that it returns `default` is a key is missing or when it's None.
It will raise a TypeError if a value is anything else but a dict or None.
Args:
d: The dict to descend into
keys: A sequence of keys to follow
default: Custom default value
"""
# Descend while we can
try:
for k in keys:
d = d[k]
# If at any step a key is missing, return default
except KeyError:
return default
# If at any step the value is not a dict...
except TypeError:
# ... if it's a None, return default. Assume it would be a dict.
if d is None:
return default
# ... if it's something else, raise
else:
raise
# If the value was found, return it
else:
return d
在第一阶段,你可以得到一个空字典。
example_dict.get('key1',{}).get('key2')
减少方法的改进很少,使其与列表一起工作。也使用数据路径作为字符串除以点,而不是数组。
def deep_get(dictionary, path):
keys = path.split('.')
return reduce(lambda d, key: d[int(key)] if isinstance(d, list) else d.get(key) if d else None, keys, dictionary)
我建议你试试蟒蛇本尼迪克特。
它是一个dict子类,提供小键盘支持等功能。
安装:pip install python-benedict
from benedict import benedict
example_dict = benedict(example_dict, keypath_separator='.')
现在你可以使用keypath访问嵌套值:
val = example_dict['key1.key2']
# using 'get' method to avoid a possible KeyError:
val = example_dict.get('key1.key2')
或者使用键列表访问嵌套值:
val = example_dict['key1', 'key2']
# using get to avoid a possible KeyError:
val = example_dict.get(['key1', 'key2'])
它在GitHub上经过了很好的测试和开源:
https://github.com/fabiocaccamo/python-benedict
注:我是这个项目的作者
我改编了GenesRus和unutbu的答案,非常简单:
class new_dict(dict):
def deep_get(self, *args, default=None):
_empty_dict = {}
out = self
for key in args:
out = out.get(key, _empty_dict)
return out if out else default
它适用于:
d = new_dict(some_data)
d.deep_get("key1", "key2", "key3", ..., default=some_value)