首页 > 解决方案 > 访问非空列表中的第一个元素时导致 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)

标签: pythonfunction

解决方案


问题出在你的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")

推荐阅读