如何在Python中检查嵌套字典中的值?

时间:2015-06-15 13:14:33

标签: python dictionary

假设我们有一个词典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键,以及它们是否实际上是字典。但这真的很冗长,而且我很确定这是一种更简单的方法,但我无法弄清楚如何做到这一点。

4 个答案:

答案 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:

  1. It found the value in question. In this case, return that value
  2. Along the way, the object is a dictionary, but does not have the requested key. In this case, a KeyError is raised
  3. The object is not a dictionary, the TypeError is raised

For 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"