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

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

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


当前回答

减少方法的改进很少,使其与列表一起工作。也使用数据路径作为字符串除以点,而不是数组。

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)

其他回答

还有一个相同功能的函数,也返回一个布尔值来表示是否找到键,并处理一些意想不到的错误。

'''
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', ''))

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

因为如果缺少一个键就会引发一个键错误是合理的,我们甚至可以不检查它,让它像这样单一:

def get_dict(d, kl):
  cur = d[kl[0]]
  return get_dict(cur, kl[1:]) if len(kl) > 1 else cur

下面是一个基于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

减少方法的改进很少,使其与列表一起工作。也使用数据路径作为字符串除以点,而不是数组。

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)

对于嵌套的字典/JSON查找,可以使用dictor

PIP安装指示器

dict对象

{
    "characters": {
        "Lonestar": {
            "id": 55923,
            "role": "renegade",
            "items": [
                "space winnebago",
                "leather jacket"
            ]
        },
        "Barfolomew": {
            "id": 55924,
            "role": "mawg",
            "items": [
                "peanut butter jar",
                "waggy tail"
            ]
        },
        "Dark Helmet": {
            "id": 99999,
            "role": "Good is dumb",
            "items": [
                "Shwartz",
                "helmet"
            ]
        },
        "Skroob": {
            "id": 12345,
            "role": "Spaceballs CEO",
            "items": [
                "luggage"
            ]
        }
    }
}

要获得龙星的物品,只需提供一个点分隔的路径,即

import json
from dictor import dictor

with open('test.json') as data: 
    data = json.load(data)

print dictor(data, 'characters.Lonestar.items')

>> [u'space winnebago', u'leather jacket']

如果键不在路径中,您可以提供回退值

你还有很多选择,比如忽略字母大小写,使用'以外的其他字符。作为路径分隔符,

https://github.com/perfecto25/dictor