Quiero tener una función que devuelva True cuando una lista de claves determinada conduzca a una estructura existente dentro del diccionario. Cada tecla corresponde al nivel de profundidad del diccionario.

La lucha que tengo es el hecho de que tanto la longitud de la Lista (= cantidad de claves) como la profundidad del diccionario son dinámicas.

#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
4
Asura 10 oct. 2019 a las 14:46

3 respuestas

La mejor respuesta

Enfoque recursivo simple:

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

Esto supone una estructura bastante uniforme: todos los valores intermedios son dictados en sí mismos y la profundidad siempre es al menos la longitud de las claves. De lo contrario, necesitaría manejar algunos errores:

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  
4
schwobaseggl 10 oct. 2019 a las 12:15

Puede definir una función recursiva que atraviese el diccionario, verificando si la clave existe en cada nivel, devolviendo False si no existe o True si la lista de claves se vacía.

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

(Como señaló schwobaseggl en otra respuesta, no debe sombrear el nombre incorporado dict).

3
Ollie 10 oct. 2019 a las 12:04

Esto recorre todos los valores y comprueba si el valor con el que estaba trabajando es un diccionario o no:

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

Un punto: no nombre sus variables dict, choca con el tipo incorporado dict.

2
Nico Griffioen 14 nov. 2019 a las 11:20
58322197