[英]How do I check value in a nested dictionary in Python?
假设我们有一个字典listD的列表,其中每个字典都嵌套了很多字典。 例如,假设listD的第一个元素是:
listD[0] = {"bar1":{"bar2":{"bar3":1234}}}
现在,我要检查listD [i] [“ bar1”] [“ bar2”] [“ bar3”] == 1234是否适用于所有i。 对于i = 0的第一个元素,这很容易,因为我们可以使用以下表达式:
listD[0]["bar1"]["bar2"]["bar3"] == 1234
但是我不能简单地写一个像这样的循环:
for dictelem in listD:
if dictelem["bar1"]["bar2"]["bar3"] == 1234:
print "equals 1234"
这是因为listD的某些字典元素可能具有以下形式:
listD[i] = {"bar1":{"bar2":"abcd"}} or
listD[i] = {"bar1":{"bar2":None}}
如果我尝试访问不存在的“ bar3”,则会出现错误。
现在,我在代码中手动指定要检查bar1,bar2和bar3键的存在以及它们是否实际上是字典。 但这确实很冗长,我很确定有一种简单的方法可以做到,但是我不知道怎么做。
def dictcheck(d, p, v):
if len(p):
if isinstance(d,dict) and p[0] in d:
return dictcheck(d[p[0]], p[1:], v)
else:
return d == v
您传递一个dict d
,一个键p
路径以及最终值以检查v
。 它将递归地输入字典,最后检查最后一个值是否等于v
。
>>> dictcheck({"bar1":{"bar2":{"bar3":1234}}}, ('bar1','bar2','bar3'), 1234)
True
>>> dictcheck({"bar1":1234}, ('bar1','bar2','bar3'), 1234)
False
因此,回答您的问题( 我想检查listD [i] [“ bar1”] [“ bar2”] [“ bar3”] == 1234是否代表所有i ):
all(dictcheck(x, ('bar1','bar2','bar3'), 1234) for x in listD)
只是这样使用try/except
块:
for dictelem in listD:
try:
if dictelem["bar1"]["bar2"]["bar3"] == 1234:
print "equals 1234"
except TypeError:
pass
在处理嵌套字典时,我将它们视为一棵树,其中的键构成了通往值的路径。 考虑到这一点,我创建了一个非递归函数dict_path
, dict_path
带有一个嵌套字典,键路径和一个值(如果找不到):
def dict_path(dic, path, value_if_not_found=None):
path = path.split('.')
try:
for key in path:
dic = dic[key]
return dic
except (KeyError, TypeError):
return value_if_not_found
listD = [
{"bar1": {"bar2": 'abcd'}},
{"bar1": {"bar2": None}},
{"bar1": {"bar2": {"bar3": 1234}}},
]
for dic in listD:
value = dict_path(dic, 'bar1.bar2.bar3')
if value == 1234:
print 'Equals 1234:', dic
该函数将继续遍历嵌套字典,直到出现以下三种情况之一:
KeyError
TypeError
对于情况2和3,我们只返回value_if_not_found
你可以试试这个
for item in listD:
if item.get("bar1",{}).get("bar2",{}).get("bar3","") == 1234:
print "yeah, gotcha"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.