python - 访问非空列表中的第一个元素时导致 IndexError 的原因是什么?
问题描述
如果这太简单了,请耐心等待,我才刚刚开始学习编码。
任务:
从 API 调用创建天气报告。查询城市,在网页上查询城市,返回未来五天的天气预报。然后再次询问城市,继续直到按下 CTRL-C。
- 我已经这样做了,它可以正常工作。
在此基础上,如果询问未退出的城市名称,请再次询问城市。
- 在这里,我的代码有问题,当我要求一个不存在的城市时,它确实要求一个新城市,我可以输入一个现有的城市,获取天气报告,但不是要求下一个城市名称,而是中断带有以下错误的代码:
City?
> fhusi
City not found
City?
> London
Here is the weather in London
2021-01-22: Heavy Cloud 6.2°C
2021-01-23: Heavy Cloud 3.8°C
2021-01-24: Heavy Rain 3.5°C
2021-01-25: Light Rain 3.8°C
2021-01-26: Showers 4.5°C
Traceback (most recent call last):
File "weather.py", line 45, in <module>
main()
File "weather.py", line 32, in main
city = search_city(query)
File "weather.py", line 19, in search_city
return seach_response[0]
IndexError: list index out of range
这是我的代码:是的,里面有很多评论,这就是我记得我的错误的方式
# pylint: disable=missing-docstring
import sys
import urllib.parse
import requests
BASE_URI = "https://www.metaweather.com"
def search_city(query):
# : Look for a given city and disambiguate between several candidates. Return one city (or None)
seach_response = requests.get("https://www.metaweather.com/api/location/search/?query="+query).json() # [0] return results as dict format
# print(requests.get("https://www.metaweather.com/api/location/search/?query="+query).json)
# print(seach_response.status_code) --> remember to remove .json() from seach to see status code
# if seach_response.status_code != 200: --> didn't work, as a empty list is returned if city doesn't exit and not an error code
if seach_response == []:
print("City not found")
main()
return seach_response[0]
def weather_forecast(woeid):
# : Return a 5-element list of weather forecast for a given woeid
weather_response = requests.get(f'https://www.metaweather.com/api/location/{woeid}/').json()
#print(weather_response) --use https://jsonformatter.curiousconcept.com/# to see the data nicely and pick relevant data
weather = weather_response['consolidated_weather'][:5]
return weather
def main():
query = input("City?\n> ")
city = search_city(query)
#print(city) --control of code
woeid = city['woeid']
forecast = weather_forecast(woeid)
# : Display weather forecast for a given city
print(f"Here is the weather in {city['title']}")
for predition in forecast:
print(f"{predition['applicable_date']}: {predition['weather_state_name']} {round(predition['the_temp'],1)}\N{DEGREE SIGN}C")
if __name__ == '__main__':
try:
while True:
main()
except KeyboardInterrupt:
print('\nGoodbye!')
sys.exit(0)
解决方案
问题出在你的search_city(query)
职能上。看看以下几行。
if seach_response == []: # empty list
print("City not found")
main() # Execute main again
# Opps, main has executed and the function is still going
# but searc_response is an empty list so search_response[0] is going to be out of bounds
return seach_response[0]
要解决上述问题,您需要return main()
代替main()
. 在此之后,main
您应该检查是否search_city(query)
返回 None。
所以你的代码应该是这样的
def search_city(query):
seach_response = requests.get("https://www.metaweather.com/api/location/search/?query="+query).json() # [0] return results as dict format
if seach_response == []:
print("City not found")
return main() # return
return seach_response[0]
并且
def main():
query = input("City?\n> ")
city = search_city(query)
if city is None:
return
woeid = city['woeid'] # here if city is None it will throw an exception
forecast = weather_forecast(woeid)
print(f"Here is the weather in {city['title']}")
for predition in forecast:
print(f"{predition['applicable_date']}: {predition['weather_state_name']} {round(predition['the_temp'],1)}\N{DEGREE SIGN}C")
推荐阅读
- python - 如何在python3中打印带有0和*的图案
- node.js - 在使用 nextjs 进行反应编译时退出状态 1
- c# - 有没有办法让 Json.Net 反序列化为声明为“对象”的属性的具体类型
- sql - 如何编写查询/创建视图以限制多条记录仅显示最大值
- node.js - 检查客户端发送的 jwt 和参数是否相等是否过大?
- python - 约束满足问题 - 错误:类对象没有属性
- vue.js - 将一个 Vue 组件模板中的类绑定到另一个 Vue 组件发出的 Window 事件
- client-server - DDD - 在不更新整个聚合根的情况下更新实体的一个小细节
- c++ - 从文件中读取数据,运算符 >>
- java - 易失性与最终领域的表现