Możesz użyć get
dwa razy:
example_dict.get('key1', {}).get('key2')
Zwróci to, None
jeśli albo nie istnieje, key1
albo key2
nie.
Zauważ, że może to nadal wywołać AttributeError
if example_dict['key1']
istnieje, ale nie jest dict (lub obiektem podobnym do dyktu z get
metodą). try..except
Kod, który pisał by podnieść TypeError
zamiast jeśli example_dict['key1']
jest unsubscriptable.
Inną różnicą jest to, że try...except
zwarcia natychmiast po pierwszym brakującym kluczu. Łańcuch get
połączeń nie.
Jeśli chcesz zachować składnię, example_dict['key1']['key2']
ale nie chcesz, aby kiedykolwiek generowała błędy KeyErrors, możesz użyć przepisu 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'>
Zwróć uwagę, że zwraca to pusty hasher, gdy brakuje klucza.
Ponieważ Hasher
jest to podklasa dict
, możesz używać Hashera w taki sam sposób, w jaki możesz użyć dict
. Wszystkie te same metody i składnia są dostępne, Hashery po prostu traktują brakujące klucze inaczej.
Możesz przekształcić zwykły dict
w Hasher
taki:
hasher = Hasher(example_dict)
i równie łatwo przekonwertuj a Hasher
na zwykły dict
:
regular_dict = dict(hasher)
Inną alternatywą jest ukrycie brzydoty w funkcji pomocniczej:
def safeget(dct, *keys):
for key in keys:
try:
dct = dct[key]
except KeyError:
return None
return dct
Więc reszta twojego kodu może pozostać stosunkowo czytelna:
safeget(example_dict, 'key1', 'key2')