为什么以下条件未在Python中停止?

时间:2018-07-23 03:37:10

标签: python while-loop

我有一个要查找其坐标的位置。但是我的功能gmaps_geoencoder错误地将地址解释为属于另一个国家。因此,我的逻辑是,不断从地址中逐个删除单词,直到返回的纬度和经度在正确的范围内(即直到它正确地解释了地址)为止。

为说明问题,下面是代码:

place = "*LORENZO GOMEZ & CO CPA'S RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"
gmaps_geoencoder(place)

>>> "{'results': [{'address_components': [{'long_name': 'San Diego', `'short_name': 'San Diego', 'types': ['locality', 'political']}, {'long_name': 'California', 'short_name': 'CA', 'types': ['administrative_area_level_1', 'political']}, {'long_name': 'United States', 'short_name': 'US', 'types': ['country', 'political']}, {'long_name': '92123', 'short_name': '92123', 'types': ['postal_code']}], 'place_id': 'ChIJAy3bGzT-24ARmX-IpDjdadk', 'types': ['doctor', 'establishment', 'health', 'point_of_interest'], 'formatted_address': '4715 Viewridge Avenue Suite 230, San Diego, CA 92123, San Diego, CA 92123, United States', 'geometry': {'location': {'lat': 32.8238366, 'lng': -117.119949}, 'location_type': 'GEOMETRIC_CENTER', 'viewport': {'southwest': {'lat': 32.8224876197085, 'lng': -117.1212979802915}, 'northeast': {'lat': 32.8251855802915, 'lng': -117.1186000197085}}}}], 'status': 'OK'}"`

我们可以看到,它实际上是在菲律宾时将其解释为属于美国。

当我从地址中删除前几个单词时,它会正确解释它:

place = "RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"
gmaps_geoencoder(place)

>>> "{'results': [{'address_components': [{'long_name': 'Rafael Castillo', 'short_name': 'Rafael Castillo', 'types': ['administrative_area_level_5', 'political']}, {'long_name': 'Agdao', 'short_name': 'Agdao', 'types': ['political', 'sublocality', 'sublocality_level_1']}, {'long_name': 'Davao City', 'short_name': 'Davao City', 'types': ['locality', 'political']}, {'long_name': 'Davao del Sur', 'short_name': 'Davao del Sur', 'types': ['administrative_area_level_2', 'political']}, {'long_name': 'Davao Region', 'short_name': 'Davao Region', 'types': ['administrative_area_level_1', 'political']}, {'long_name': 'Philippines', 'short_name': 'PH', 'types': ['country', 'political']}], 'partial_match': True, 'types': ['administrative_area_level_5', 'political'], 'place_id': 'ChIJi4qcxTBs-TIRfnWnF4MGzDE', 'formatted_address': 'Rafael Castillo, Agdao, Davao City, Davao del Sur, Philippines', 'geometry': {'location': {'lat': 7.100270999999999, 'lng': 125.6382528}, 'bounds': {'southwest': {'lat': 7.095814, 'lng': 125.6311701}, 'northeast': {'lat': 7.1040211, 'lng': 125.644075}}, 'location_type': 'APPROXIMATE', 'viewport': {'southwest': {'lat': 7.095814, 'lng': 125.6311701}, 'northeast': {'lat': 7.1040211, 'lng': 125.644075}}}}, {'address_components': [{'long_name': 'Pelayo Street', 'short_name': 'Pelayo St', 'types': ['route']}, {'long_name': 'Poblacion District', 'short_name': 'Poblacion District', 'types': ['political', 'sublocality', 'sublocality_level_1']}, {'long_name': 'Davao City', 'short_name': 'Davao City', 'types': ['locality', 'political']}, {'long_name': 'Davao del Sur', 'short_name': 'Davao del Sur', 'types': ['administrative_area_level_2', 'political']}, {'long_name': 'Davao Region', 'short_name': 'Davao Region', 'types': ['administrative_area_level_1', 'political']}, {'long_name': 'Philippines', 'short_name': 'PH', 'types': ['country', 'political']}], 'partial_match': True, 'types': ['route'], 'place_id': 'ChIJJaE5cndt-TIRqYbFlmdcZP4', 'formatted_address': 'Pelayo St, Poblacion District, Davao City, Davao del Sur, Philippines', 'geometry': {'location': {'lat': 7.0685545, 'lng': 125.6068616}, 'bounds': {'southwest': {'lat': 7.0662803, 'lng': 125.6049452}, 'northeast': {'lat': 7.0718272, 'lng': 125.6078379}}, 'location_type': 'GEOMETRIC_CENTER', 'viewport': {'southwest': {'lat': 7.0662803, 'lng': 125.6049452}, 'northeast': {'lat': 7.0718272, 'lng': 125.6078379}}}}], 'status': 'OK'}")

因此,要针对其他此类错误识别的地址自动执行此过程(删除多少个单词),我的代码如下:

place = "*LORENZO GOMEZ & CO CPA'S RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"
lat = 0
lon = 0
while ((lat not in range(4,21)) or (lon not in range(116,128))): # Philippines' latitude and longitude range
    place = place.split(' ', 1)[1]
    try:
        lat, lon, res = gmaps_geoencoder(place)
    except: # This is because sometimes the gmaps API does not return any result for a given address. In that case, remove the word at the beginning and search again.
        place = place.split(' ', 1)[1]
        lat, lon, res = gmaps_geoencoder(place)

但是,这会一直剥离单词,直到剥离最后一个单词并返回list index out of range错误。当latlon处于代码中指示的所需范围内时,为什么while条件不会停止?

编辑:修改while条件以使其始终运行,并添加if ... break以在达到所需条件时停止while循环,从而解决了以下问题:< / p>

while True: 
    place = place.split(' ', 1)[1]
    try:
        lat, lon, res = gmaps_geoencoder(place)
    except:
        place = place.split(' ', 1)[1]
        lat, lon, res = gmaps_geoencoder(place)
    if (4<lat<21 or 116<lon<128):
        break

3 个答案:

答案 0 :(得分:1)

之所以不起作用,是因为lat和lon可以是非整数,而您只检查整数。试试这个:

while (not 4 <= lat <= 21) or (not 116 <= lon <= 128):
    ... 

不起作用的原因是range(4,21)正在生成此列表(请阅读EDIT进行澄清):

[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

如果纬度是一个十进制数字(从它的外观来看,它是),那么它将计算该列表中的十进制数字,而不是十进制数字。

编辑:谢谢abanert向我指出这一点。 range()不会产生列表,但是会产生一个范围对象。这与列表非常相似,您可以在其中使用“ x in range()”来检查某物是否为其生成的项目之一。我仍然认为这是正确的答案,但起初是令人误解的。部分原因是我自己的错,认为范围是发电机。

答案 1 :(得分:1)

您的latlon似乎不是整数,但是对于x in range(4,8),它与x in [4,5,6,7]类似,它将仅考虑整数之间的相等性。

也许您希望将一段时间的条件从lat not in range(4,21)更改为lat>21 or lat<4

答案 2 :(得分:-1)

由于在这种情况下只有几个词,也许您应该尝试仅打印gmaps_encoder的输出以查看发生了什么?我认为您正确删除了第一个单词,所以当place =“ RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES”时,循环的输出是什么?