Это именно то, для чего try-except
предназначен:
try:
print(location.raw['address']['town'])
except KeyError:
print(location.raw['address']['city'])
Альтернатива
Некоторые люди, осведомленные о производительности, скажут: «Но попробуйте, кроме как дорого».
Вы можете использовать некоторые другие альтернативы:
if 'town' in location.raw['address']: ... else: ...
location.raw['address'].get('town', location.raw['address'].get('city'))
У каждого подхода есть свои плюсы и минусы. .get
, например, не ленивый. location.raw['address'].get('city')
воля
оцениваться до того, как 'town'
будет проверен, так что на самом деле это больше
расточительный и контрпродуктивный.
Подход if-else
(в зависимости от того, как он используется), вероятно, должен будет дважды хешировать один из ключей.
Я думаю, что достаточно поместить более общий ключ в блок try
.
Давайте проведем несколько тестов:
from timeit import Timer
from random import choice
list_of_dicts = [{choice(('town', 'city')): 1} for _ in range(2000)]
def try_except():
for d in list_of_dicts:
try:
d['town']
except KeyError:
d['city']
def if_else():
for d in list_of_dicts:
if 'town' in d:
d['town']
else:
d['city']
def get():
for d in list_of_dicts:
d.get('town', d.get('city'))
print(min(Timer(try_except).repeat(10, 10)))
print(min(Timer(if_else).repeat(10, 10)))
print(min(Timer(get).repeat(10, 10)))
Это выводит
0.0053282611981659705
0.0018278721105344786
0.00536558375274554
означает, что в этом примере из 2000 словарей if-else
был самым быстрым (хотя ему нужно дважды хэшировать один из ключей), а try-except
и get
были примерно одинаковыми.