Método seguro de Python para obtener valor del diccionario nested

Tengo un diccionario nested. ¿Hay una sola forma de obtener valores de forma segura?

try: example_dict['key1']['key2'] except KeyError: pass 

¿O tal vez Python tiene un método como get() para el diccionario nested?

Podrías usar get dos veces:

 example_dict.get('key1', {}).get('key2') 

Esto devolverá None si key2 o key2 no existen.

Tenga en cuenta que esto aún podría generar un AttributeError si example_dict['key1'] existe, pero no es un dict (o un objeto similar a dict con un método get ). El código try..except que publicaste generaría un TypeError en su lugar si example_dict['key1'] es susceptible de suscripción.

Otra diferencia es que el try...except cortocircuitos inmediatamente después de la primera clave faltante. La cadena de llamadas no lo hace.


Si desea conservar la syntax, example_dict['key1']['key2'] pero no desea que se suba KeyErrors, entonces podría usar la receta Hasher :

 class Hasher(dict): # https://stackoverflow.com/a/3405143/190597 def __missing__(self, key): value = self[key] = type(self)() return value example_dict = Hasher() print(example_dict['key1']) # {} print(example_dict['key1']['key2']) # {} print(type(example_dict['key1']['key2'])) #  

Tenga en cuenta que esto devuelve un Hasher vacío cuando falta una clave.

Como Hasher es una subclase de dict , puedes usar un Hasher de la misma manera que podrías usar un dict . Todos los mismos métodos y syntax están disponibles, Hashers simplemente trata las claves que faltan de manera diferente.

Puede convertir un dict regular en un Hasher como este:

 hasher = Hasher(example_dict) 

y convierte un Hasher a un dict regular con la misma facilidad:

 regular_dict = dict(hasher) 

Otra alternativa es ocultar la fealdad en una función auxiliar:

 def safeget(dct, *keys): for key in keys: try: dct = dct[key] except KeyError: return None return dct 

Entonces, el rest de tu código puede mantenerse relativamente legible:

 safeget(example_dict, 'key1', 'key2')