Python : check if the nested dictionary exist

Question:

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

Asked By: Luigi T.

||

Answers:

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…

Answered By: Pedro Lobito

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.

Answered By: Jared Goguen

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

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

if present: 
    ...

To get the element:

try:
    obj = dict1['layer1']['layer2'][0]['layer3']
except KeyError:
    obj = None  # or whatever
Answered By: Kirill Bulygin

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

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

Answered By: Alexander

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.

Answered By: Ulises Torelli

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.

Answered By: rorance_
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.