I have a JSON dict like the following :
"{
"a":1,
"b":{
"b1":False,
"b2":{"b21": 2, "b22":8}
},
"c": {
"b1":True,
"b2":2,
"b4":8
},
"d":{
"b1":False,
"d1":89
}
}"
I want to check the value of the key "b1"
in the dictionary, and get out when I find b1=True
. 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 b1=True
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 :
found=True
break
else:
isb1True(value)
return found
My code always returns False
.
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})
True
>>> isb1true({'b1': False})
False
>>> isb1true({'b': {'b1': True}})
True
>>> isb1true({'b': {'b1': False}})
False
>>> isb1true({'b': {'c': True, 'spam': 'eggs', 'ham': {'bar': 'baz', 'b1': True}}})
True
>>> isb1true({'b': {'c': True, 'spam': 'eggs', 'ham': {'bar': 'baz'}}})
False