Python 从嵌套字典中获取值

Python 从嵌套字典中获取值,python,idioms,Python,Idioms,是否有一种从嵌套字典中获取值的标准方法?这个函数相对来说比较容易编写,但我很好奇PSL或语言本身是否已经有一些东西可以这样使用 下面是我的意思的例子: def grab_from_dict(d, *keys): assert isinstance(d, dict), 'd must be of type dict' current_dict = d for key in keys[0 : -1]: if key not in current_dict:

是否有一种从嵌套字典中获取值的标准方法?这个函数相对来说比较容易编写,但我很好奇PSL或语言本身是否已经有一些东西可以这样使用

下面是我的意思的例子:

def grab_from_dict(d, *keys):
    assert isinstance(d, dict), 'd must be of type dict'

    current_dict = d
    for key in keys[0 : -1]:
        if key not in current_dict:
            return None

        current_dict = current_dict[key]

    if current_dict is None:
        return None

    return current_dict.get(keys[-1], None)

d = {
    'a' : {
        'b' : {
           'c1' : {
                'd' : 'leeloo'
            },
           'c2' : {
                'd' : None
            },
           'c3' : {
                'e' : None
            },
            'c4' : None
        }
    }
}

print grab_from_dict(d, 'a', 'b', 'c1')
> {'d': 'leeloo'}
print grab_from_dict(d, 'a', 'b', 'c1', 'd')
> leeloo
print grab_from_dict(d, 'a', 'b', 'c2')
> {'d': None}
print grab_from_dict(d, 'a', 'b', 'c2', 'd')
> None
print grab_from_dict(d, 'a', 'b', 'c3')
> {'e': None}
print grab_from_dict(d, 'a', 'b', 'c3', 'd')
> None
print grab_from_dict(d, 'a', 'b', 'c4')
> None
print grab_from_dict(d, 'a', 'b', 'c4', 'd')
> None
print grab_from_dict(d, 'a', 'b', 'c5')
> None
print grab_from_dict(d, 'a', 'b', 'c5', 'd')
> None
这为我提供了一种在嵌套字典中深入获取值的方法,而不用担心父字典的存在。因此,与其写这封信:

value = None
if 'a' in d and d['a'] not None:
    if 'b' in d['a'] and d['a']['b'] is not None:
        if 'c1' in d['a']['b'] and d['a']['b']['c1'] is not None:
            value = d['a']['b']['c1'].get('d', None)
print value
> leeloo
我可以这样写:

value = grab_from_dict(d, 'a', 'b', 'c1', 'd')
print value
> leeloo
如果缺少任何父级,则函数只返回None:

value = grab_from_dict(d, 'a', 'a', 'c1', 'd')
print value
> None

你为什么要找一个函数?这不包括你要找的吗

>>> d['a']['b']['c1']
{'d': 'leeloo'}
>>> d['a']['b']['c1']['d']
'leeloo'

捕获异常应该有效:

try:
    result = d['a']['b']['c1']
except KeyError:
    result = None

您可以编写/查找使用这种行为编写的自定义容器类(如果您尝试获取密钥,可能它有一个返回自身的NoneDict对象),但更优雅的解决方案可能是try/except块:

try:
    x = d['a']['b']['c5']['d']
except KeyError:
    x = None

因为这实际上只是告诉程序如何处理预期错误。我把这个小代码块称为“pythonic”方法。

好吧,那就是
d['a']['b']['c1']
。那里真的不需要函数…
reduce(dict.get,keys,the_dict)
。(在python3中,您必须从functools import reduce导入
)。对于缺少的键,您可能希望提供一个不会引发错误的更好的第一个参数(未测试:
lambda d,key:d.get(key),如果d不是None,则为None
),不需要函数,除非您希望进行错误检查。:)我添加了另外一个例子来澄清我的问题的动机。虽然我同意这会起作用,但我想毫无例外地表达代码中非常常见的情况。