我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?

try:
    example_dict['key1']['key2']
except KeyError:
    pass

或者python有一个类似get()的方法用于嵌套字典?


当前回答

根据Yoav的回答,一个更安全的方法是:

def deep_get(dictionary, *keys):
    return reduce(lambda d, key: d.get(key, None) if isinstance(d, dict) else None, keys, 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', ''))

(真的,大声叫) (假的,”)

在第一阶段,你可以得到一个空字典。

example_dict.get('key1',{}).get('key2')

我改编了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)

你可以使用pydash:

import pydash as _  #NOTE require `pip install pydash`

_.get(example_dict, 'key1.key2', default='Default')

https://pydash.readthedocs.io/en/latest/api.html

根据Yoav的回答,一个更安全的方法是:

def deep_get(dictionary, *keys):
    return reduce(lambda d, key: d.get(key, None) if isinstance(d, dict) else None, keys, dictionary)