Reputation: 43
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
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
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
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