假设我们有一个词典listD列表,其中每个词典都嵌入了更多的词典。例如,假设listD的第一个元素是:
listD[0] = {"bar1":{"bar2":{"bar3":1234}}}
现在我想检查所有i的listD [i] [" bar1"] [" bar2"] [" bar3"] == 1234。对于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键,以及它们是否实际上是字典。但这真的很冗长,而且我很确定这是一种更简单的方法,但我无法弄清楚如何做到这一点。
答案 0 :(得分:1)
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
您传递了一个字典d
,一个键p
路径,以及检查v
的最终值。它将以递归方式进入dicts,最后检查最后一个值是否等于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 for all i ): / p>
all(dictcheck(x, ('bar1','bar2','bar3'), 1234) for x in listD)
答案 1 :(得分:0)
以这种方式使用try/except
块:
for dictelem in listD:
try:
if dictelem["bar1"]["bar2"]["bar3"] == 1234:
print "equals 1234"
except TypeError:
pass
答案 2 :(得分:0)
When dealing with nested dictionaries, I think of them as a tree where the keys make up the path to the value. With that in mind, I created a non-recursive function, dict_path
with takes in a nested dictionary, the key path, and a value in case not found:
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
The function keeps traversing the nested dictionary until one of these three conditions occur:
KeyError
is raisedTypeError
is raisedFor case 2 and 3, we simply return value_if_not_found
答案 3 :(得分:-1)
你可以试试这个
for item in listD:
if item.get("bar1",{}).get("bar2",{}).get("bar3","") == 1234:
print "yeah, gotcha"