Samiella Samiella - 1 year ago 49
Python Question

Iterate over nested keys in Python dict and break on first occurence

I have a JSON dict like the following :

"b2":{"b21": 2, "b22":8}
"c": {

I want to check the value of the key
in the dictionary, and get out when I find
. If I check the entire dict (nested keys included), and I don't find b1=True, then I would like to return False. For the example above, my function should return True.

Basically I want to break the code on the first occurrence of
and iterate over all the keys of the dict (in all levels), and if this occurrence does not exist, return False.

This is what I came up with :

def isb1True(jsonDoc):
found = False
for (key,value) in jsonDoc.iteritems():
if key=='b1':
if value==True :
return found

My code always returns

Answer Source

You need to return from the recursive calls too, and use that to inform wether or not you are going to continue looping; your code ignores what the recursive isb1True(value) call returns.

You can use the any() function to short-circuit testing recursive values:

def isb1true(d):
    if not isinstance(d, dict): return False
    return any(v if k == 'b1' else isb1true(v) for k, v in d.iteritems())

The above recurses for any key that is not 'b1', and recursion stops when that value is not a dictionary (in which case it won't be b1 so that result is not a 'b1': True case).

I'm assuming that 'b1' is always set to a boolean; the above returns True for any 'truthy' value for that key.

Some test cases:

>>> isb1true({'b1': True})
>>> isb1true({'b1': False})
>>> isb1true({'b': {'b1': True}})
>>> isb1true({'b': {'b1': False}})
>>> isb1true({'b': {'c': True, 'spam': 'eggs', 'ham': {'bar': 'baz', 'b1': True}}})
>>> isb1true({'b': {'c': True, 'spam': 'eggs', 'ham': {'bar': 'baz'}}})