Reputation: 362
Let's say I have a nested dict, e.g. the following
{'agent1': {'status': True},
'block1': {'status': True, 'number': False, 'usable_by': True, 'location': True, 'skill':
{'speed': False, 'flexibility': True}}}
At the lowest key level (the leaves) of this dict, the values are only boolean (True or False). The input dict can basically have any kind of nested structure with different names as keys and no fixed depth.
How can I check in general, whether there is False
in a given dict.
Upvotes: 1
Views: 1431
Reputation: 1459
Convert your nested dictionary to a NestedDict
from ndicts.ndicts import NestedDict
d = {
'agent1': {
'status': True
},
'block1': {
'status': True,
'number': False,
'usable_by': True,
'location': True,
'skill': {'speed': False, 'flexibility': True}
}
}
nd = NestedDict(d)
Then get the answer with a one liner
>>> all(nd.values())
False
To install ndicts pip install ndicts
Upvotes: 0
Reputation: 690
To traverse the nested dict, you can use recursion. See (Loop through all nested dictionary values?)
def contains_false(d):
for k,v in d.iteritems():
if isinstance(v, dict):
# recurse into nested-dict
if contains_false(v):
return True
# Check value of leaf-node. Exit early
# if we find a 'False' value.
if v is False:
return True
# no 'False' values found
return False
>>> d = {1:True, 2:{1:True, 2:True}, 3:{1:True, 2:True, 3:{1:False}}}
>>> contains_false(d)
True
>>> d[3][3][1] = True
>>> contains_false(d)
False
This is assuming that you don't need to know the key(s) to reach the 'False' value.
Upvotes: 1
Reputation: 1122372
You'd have to traverse the dictionaries, and you want to exit early:
def any_false_leaf(d):
if isinstance(d, dict):
return any(any_false_leaf(v) for v in d.values())
return not d
This recurses through your dictionaries, and returns True
if there is a nested false value in the structure. Using the any()
function and a generator expression guarantees that the result is produced as soon as such a value is found.
Demo:
>>> d = {'agent1': {'status': True},
... 'block1': {'status': True, 'number': False, 'usable_by': True, 'location': True, 'skill':
... {'speed': False, 'flexibility': True}}}
>>> any_false_leaf(d)
True
>>> any_false_leaf({'foo': True})
False
>>> any_false_leaf({'foo': {'bar': True}})
False
>>> any_false_leaf({'foo': {'bar': True, 'spam': False}})
True
Upvotes: 3
Reputation: 348
A quick solution can be:
d = {'block1': {'status': True, 'usable_by': True, 'skill': {'flexibility': True, 'speed': False}, 'number': False, 'location': True}, 'agent1': {'status': True}}
values = []
def find_false(d):
for k in d.keys():
if isinstance(d[k], dict):
find_false(d[k])
else:
values.append(d[k])
find_false(d)
print(False in values)
Hope this helps.
Upvotes: 0