Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 570
Asura Avatar asked Dec 31 '22 14:12

Asura


2 Answers

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  
like image 93
user2390182 Avatar answered Jan 30 '23 05:01

user2390182


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.)

like image 25
Ollie Avatar answered Jan 30 '23 04:01

Ollie