Asura
Asura

Reputation: 43

Check if Key Structure exists in Dictionary

I want to have a function that returns True when a given list of keys lead to an existing structure inside the dictionary. Each key corresponds to the depth level of the dictionary

The struggle that I have is the fact that both the length of the List (= amount of Keys) and the depth of the dictionary are dynamic

#Example Code:

keys1 = ["K1", "K3", "K4"]
keys2 = ["K2", "K6"]
keys3 = ["K1", "K6", "K4"]

dict = {
    "K1": {
        "K3": {
            "K4": "a"
        }
    },
    "K2": {
        "K6": "b"
    }
}

result = function(keys1, dict) #result should be True    
result = function(keys2, dict) #result should be True    
result = function(keys3, dict) #result should be False

Upvotes: 4

Views: 374

Answers (3)

Nico Griffioen
Nico Griffioen

Reputation: 5405

This loops through all values and checks if the value were working with is a dictionary or not:

def function(keys, dictionary):
    for value in keys1:
        if not isinstance(dictionary,dict) or value not in dictionary:
            return False
        dictionary = dictionary[value]
    return True

One point: don't name your variables dict, it clashes with the built-in type dict.

Upvotes: 2

user2390182
user2390182

Reputation: 73470

Simple recursive approach:

def function(keys, dct):
    return not keys or (keys[0] in dct and function(keys[1:], dct[keys[0]]))

>>> function(keys1, dct)  # never shadow built-in names
True
>>> function(keys2, dct)
True
>>> function(keys3, dct)
False

This assumes a quite uniform structure: all intermediate values are dicts themselves and the depth is always at least the length of the keys. Otherwise, you would need to handle some errors:

def function(keys, dct):
    try:
        return not keys or function(keys[1:], dct[keys[0]])
    except (TypeError, KeyError):  # this allows you to shorten the above
        return False  

Upvotes: 4

Ollie
Ollie

Reputation: 1712

You can define a recursive function that traverses the dictionary, checking if the key exists at each level, returning False if it doesn't or True if the list of keys becomes empty.

def function(keys, dictionary):
    if len(keys) == 0:
        return True
    elif keys[0] in dictionary:
        return function(keys[1:], dictionary[keys[0]])
    else:
        return False

(As schwobaseggl pointed out in another answer, you shouldn't shadow the built-in name dict.)

Upvotes: 3

Related Questions