Puedes usar get
dos veces:
example_dict.get('key1', {}).get('key2')
Esto volverá None
si existe key1
o key2
no existe.
Tenga en cuenta que esto aún podría generar un AttributeError
if example_dict['key1']
, pero no es un dict (o un objeto similar a un dict con un get
método). El try..except
código que publicó generaría un TypeError
lugar si no example_dict['key1']
se puede suscribir.
Otra diferencia es que los try...except
cortocircuitos inmediatamente después de la primera clave faltante. La cadena de get
llamadas no.
Si desea preservar la sintaxis, example_dict['key1']['key2']
pero no desea que aumente nunca KeyErrors, puede 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']))
# <class '__main__.Hasher'>
Tenga en cuenta que esto devuelve un Hasher vacío cuando falta una clave.
Dado que Hasher
es una subclase de dict
usted, puede usar un Hasher de la misma manera que podría usar un dict
. Todos los mismos métodos y sintaxis están disponibles, Hashers solo trata las claves faltantes de manera diferente.
Puede convertir una regular dict
en una Hasher
como esta:
hasher = Hasher(example_dict)
y convierta a Hasher
a regular con la dict
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 resto de su código puede permanecer relativamente legible:
safeget(example_dict, 'key1', 'key2')