深入到几个级别的嵌套字典(可能不存在)

时间:2015-06-16 15:40:55

标签: python dictionary

我有一个我调用的API返回一个字典。该词典的一部分本身就是另一本词典。在那个内部字典中,有一些键可能不存在,或者它们可能存在。这些键可以引用另一个字典。

举个例子,说我有以下词典:

dict1 = {'a': {'b': {'c':{'d':3}}}}
dict2 = {'a': {'b': {''f': 2}}}

我想编写一个我可以在字典中传递的函数,以及一个能够引导我进入3 dict12 {}的密钥列表{1}}。但是,dict2中可能不存在bc,而dict1中可能不存在bf。< / p>

我想要一个我可以这样称呼的功能:

dict2

然后返回3,或者如果找不到键,则返回默认值0。

我知道我可以使用这样的东西:

get_value(dict1, ['a', 'b', 'c'])

但这对我来说似乎很啰嗦。

我也可以压扁字典(见https://stackoverflow.com/a/6043835/1758023),但这可能有点密集,因为我的字典实际上相当大,并且在某些键中有大约5个嵌套级别。而且,我只需要从字典中得到两件事。

现在我在SO问题中使用val = dict1.get('a', {}).get('b', {}).get('c', 0) 函数,但这似乎对我的情况有点过分。

3 个答案:

答案 0 :(得分:3)

如果没有递归,只需遍历键,一次下一级。将其放在try / except内可以处理丢失的密钥案例。当密钥不存在时,KeyError将被提升,如果你点击&#34;底部&#34;将TypeError。该词典过早,并尝试将[]运算符应用于int或其他内容。

def get_value(d, ks):
    for k in ks:
        try:
            d = d[k] # descend one level
        except (KeyError, TypeError):
            return 0 # when any lookup fails, return 0
    return d # return the final element

答案 1 :(得分:2)

您可以使用递归函数:

def get_value(mydict, keys):
    if not keys:
        return mydict
    if keys[0] not in mydict:
        return 0
    return get_value(mydict[keys[0]], keys[1:])

如果键不仅可以丢失,而且可以是其他非dict类型,您可以像这样处理:

def get_value(mydict, keys):
    if not keys:
        return mydict
    key = keys[0]
    try:
        newdict = mydict[key]
    except (TypeError, KeyError):
        return 0
    return get_value(newdict, keys[1:])

答案 2 :(得分:0)

这是一个适用于一般情况的递归函数

def recursive_get(d, k):
    if len(k) == 0:
        return 0
    elif len(k) == 1:
        return d.get(k[0], 0)       
    else:
        value = d.get(k[0], 0)
        if isinstance(value, dict):
            return recursive_get(value, k[1:])
        else:
            return value

它需要dict的搜索参数和一个键列表,每个级别检查一个

>>> dict1 = {'a': {'b': {'c':{'d':3}}}}
>>> recursive_get(dict1, ['a', 'b', 'c'])
{'d': 3}

>>> dict2 = {'a': {'b': {'f': 2}}}
>>> recursive_get(dict2, ['a', 'b', 'c'])
0