我有一个我调用的API返回一个字典。该词典的一部分本身就是另一本词典。在那个内部字典中,有一些键可能不存在,或者它们可能存在。这些键可以引用另一个字典。
举个例子,说我有以下词典:
dict1 = {'a': {'b': {'c':{'d':3}}}}
dict2 = {'a': {'b': {''f': 2}}}
我想编写一个我可以在字典中传递的函数,以及一个能够引导我进入3
dict1
和2
{}的密钥列表{1}}。但是,dict2
中可能不存在b
和c
,而dict1
中可能不存在b
和f
。< / 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)
函数,但这似乎对我的情况有点过分。
答案 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