Luigi T.
Luigi T.

Reputation: 545

Python : check if the nested dictionary exist

I have several nested dictionaries within lists, and I need to verify if a specific path exist e.g.

dict1['layer1']['layer2'][0]['layer3']

How can I check with an IF statement if the path is valid?

I was thinking to

if dict1['layer1']['layer2'][0]['layer3'] :

but it doesn't work

Upvotes: 5

Views: 12769

Answers (6)

Kirill Bulygin
Kirill Bulygin

Reputation: 3826

Here's the explicit short code with try/except:

try:
    dict1['layer1']['layer2'][0]['layer3']
except (KeyError, IndexError):
    present = False
else:
    present = True

if present: 
    ...

To get the element:

try:
    obj = dict1['layer1']['layer2'][0]['layer3']
except (KeyError, IndexError):
    obj = None  # or whatever

Upvotes: 6

rorance_
rorance_

Reputation: 369

I wanted to propose another solution, because I've been thinking about it too.

if not dict1.get("layer1", {}).get("layer2", {})[0].get("layer3", {}):
    ...

dict.get() attempts to get the key at each stage. If the key is not present, an empty dict will be returned, instead of the nested dict (this is needed, because trying to call .get() on the default return of None will yield an AttributeError). If the return is empty, it will evaluate to false. So, this wouldn't work if the final result was an empty dict anyway, but if you can guarantee the results will be filled, this is an alternative that is fairly simple.

Upvotes: 2

Ulises Torelli
Ulises Torelli

Reputation: 81

Using recursive function:

def path_exists(path, dict_obj, index = 0):
    if (type(dict_obj) is dict and path[index] in dict_obj.keys()):
        if (len(path) > (index+1)):
            return path_exists(path, dict_obj[path[index]], index + 1)
        else:
            return True
    else:
        return False

Where path is a list of strings representing the nested keys.

Upvotes: 0

Alexander
Alexander

Reputation: 7842

Here is a similar question with the answer I would recommend:

Elegant way to check if a nested key exists in a python dict

Upvotes: 0

Jared Goguen
Jared Goguen

Reputation: 9010

If you don't want to go the try/except route, you could whip up a quick method to do this:

def check_dict_path(d, *indices):
    sentinel = object()
    for index in indices:
        d = d.get(index, sentinel)
        if d is sentinel:
            return False
    return True


test_dict = {1: {'blah': {'blob': 4}}}

print check_dict_path(test_dict, 1, 'blah', 'blob') # True
print check_dict_path(test_dict, 1, 'blah', 'rob') # False

This might be redundant if you're also trying to retrieve the object at that location (rather than just verify whether the location exists). If that's the case, the above method can easily be updated accordingly.

Upvotes: 3

Pedro Lobito
Pedro Lobito

Reputation: 98931

As far as I know, you've to go step by step, i.e.:

if 'layer1' in dict1:
   if 'layer2' in dict1['layer1']

ans so on...

Upvotes: 0

Related Questions