我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
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
其他回答
还有一个相同功能的函数,也返回一个布尔值来表示是否找到键,并处理一些意想不到的错误。
'''
json : json to extract value from if exists
path : details.detail.first_name
empty path represents root
returns a tuple (boolean, object)
boolean : True if path exists, otherwise False
object : the object if path exists otherwise None
'''
def get_json_value_at_path(json, path=None, default=None):
if not bool(path):
return True, json
if type(json) is not dict :
raise ValueError(f'json={json}, path={path} not supported, json must be a dict')
if type(path) is not str and type(path) is not list:
raise ValueError(f'path format {path} not supported, path can be a list of strings like [x,y,z] or a string like x.y.z')
if type(path) is str:
path = path.strip('.').split('.')
key = path[0]
if key in json.keys():
return get_json_value_at_path(json[key], path[1:], default)
else:
return False, default
使用示例:
my_json = {'details' : {'first_name' : 'holla', 'last_name' : 'holla'}}
print(get_json_value_at_path(my_json, 'details.first_name', ''))
print(get_json_value_at_path(my_json, 'details.phone', ''))
(真的,大声叫) (假的,”)
递归解。它不是最有效的,但我发现它比其他示例更具可读性,而且它不依赖于functools。
def deep_get(d, keys):
if not keys or d is None:
return d
return deep_get(d.get(keys[0]), keys[1:])
例子
d = {'meta': {'status': 'OK', 'status_code': 200}}
deep_get(d, ['meta', 'status_code']) # => 200
deep_get(d, ['garbage', 'status_code']) # => None
一个更精致的版本
def deep_get(d, keys, default=None):
"""
Example:
d = {'meta': {'status': 'OK', 'status_code': 200}}
deep_get(d, ['meta', 'status_code']) # => 200
deep_get(d, ['garbage', 'status_code']) # => None
deep_get(d, ['meta', 'garbage'], default='-') # => '-'
"""
assert type(keys) is list
if d is None:
return default
if not keys:
return d
return deep_get(d.get(keys[0]), keys[1:], default)
我改编了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)
在第一阶段,你可以得到一个空字典。
example_dict.get('key1',{}).get('key2')
如果您想使用另一个库来解决问题,这是最好的方法
https://github.com/maztohir/dict-path
from dict-path import DictPath
data_dict = {
"foo1": "bar1",
"foo2": "bar2",
"foo3": {
"foo4": "bar4",
"foo5": {
"foo6": "bar6",
"foo7": "bar7",
},
}
}
data_dict_path = DictPath(data_dict)
data_dict_path.get('key1/key2/key3')