Как поддержать "город" и "город" при запросе Nominatim? - PullRequest
0 голосов
/ 27 августа 2018

Обратное геокодирование с помощью Nominatim возвращает либо «город», либо «город» в зависимости от размера местоположения.

import geojson
from geopy.geocoders import Nominatim

location = "48.84837905, 2.28229522311902"
geolocator = Nominatim(user_agent="my-application",timeout=3)
location = geolocator.reverse(location)
print(location.raw)
#Sometimes "town", sometimes "city"
##print(location.raw['address']['town'])
##print(location.raw['address']['city'])

Какой хороший способ справиться с обоими случаями?

Спасибо.

1 Ответ

0 голосов
/ 27 августа 2018

Это именно то, для чего 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 были примерно одинаковыми.

...