【问题标题】:Fixing IndexError: List out of range issues修复 IndexError:列出超出范围的问题
【发布时间】:2018-11-03 11:21:37
【问题描述】:

我正在处理一个 .csv 文件,我编写了这段代码来计算 year 列中每个值在 csv 数据集中出现的次数。

每当我在我的个人系统上运行代码时,我都会在第 10 行 row_year = suspension[5] 收到 IndexError: list out of range,但是当我在 dataquest 站点上运行代码时,代码运行良好。

csv 数据集有 7 列,第 5 列代表

import csv

file  = open("nfl_suspensions_data.csv")
nfl_suspensions = list(csv.reader(file))
nfl_suspensions = nfl_suspensions[1:]

years = {}

for suspension in nfl_suspensions:
    row_year = suspension[5]
    if row_year in years:
        years[row_year] = years[row_year] + 1
    else:
        years[row_year] = 1

print(years)

【问题讨论】:

    标签: python python-3.x list dictionary


    【解决方案1】:

    您的数据太短 - 您索引到它后面的列表中。如果你真的有year 作为第 5 列,你应该使用column[4] 来访问它——python 索引是基于 0 的。

    使用error handling:

    import csv
    
    file  = open("nfl_suspensions_data.csv")
    nfl_suspensions = list(csv.reader(file))
    nfl_suspensions = nfl_suspensions[1:]
    
    years = {}
    
     for line_nr, suspension in enumerate(nfl_suspensions):
        try:
            row_year = suspension[5]
        except IndexError:
            # 0 based line_nr, line_nr + 1 due to removed header line  
            print("Data corrupt: less then 6 entries. Line:", line_nr+1)
            print(suspension)
    
            # skip this data
            continue
    
        if row_year in years:
            years[row_year] = years[row_year] + 1
        else:
            years[row_year] = 1
    
    print(years)
    

    这遵循蟒蛇Ask forgiveness not permission哲学。


    你也应该切换到

    with open("nfl_suspensions_data.csv") as file:
        nfl_suspensions = list(csv.reader(file))[1:]
    

    这是读取文件的首选方式。见python.org - reading and writing files(见第二个代码示例块)

    您也可以利用collections.defaultdict

    years = defaultdict(int) # above 
    

    并删除周围的 if 检查

    # if row_year in years:
        years[row_year] += 1  # this should work using a defaultdict(int)
    # else:
    #    years[row_year] = 1
    

    或使用collections.Counter


    更短的代码,包括完成任务的文件生成(第 [5] 行 == 第 6 列的年份):

    import csv
    from collections import Counter
    
    
    # Create a demo data file with errors:    
    with open("nfl_suspensions_data.csv","w") as f:
        for inter in range(1,10):
            for y in range(1980,2001,inter):
                f.write(f"na,na,na,na,na,{y},na,na\n")
            # corrupt line
            f.write(f"na,na,na,na\n")
    
    
    # process and count the years:
    with open("nfl_suspensions_data.csv") as file:
        nfl_suspensions = list(csv.reader(file))[1:]
    
    as_columns = list(zip(*[l for l in nfl_suspensions if len(l) > 6]))
    print(Counter(as_columns[5]))
    

    输出:

    Counter({'1980': 8, '1992': 5, '1998': 5, '1986': 4, '1988': 4, '1996': 4,
             '2000': 4, '1984': 3, '1989': 3, '1990': 3, '1994': 3, '1995': 3, 
             '1982': 2, '1983': 2, '1985': 2, '1987': 2, '1981': 1, '1991': 1, 
             '1993': 1, '1997': 1, '1999': 1})
    

    您的逻辑已修复,应用于上面生成的数据:

    def your_code_fixed(sus):
        years = {}
        for line_nr, suspension in enumerate(sus):
            try:
                row_year = suspension[5]
            except IndexError:
                # 0 based line_nr, line_nr + 1 due to removed header line  
                print("Data corrupt: less then 6 entries. Line:", line_nr+1)
                print(suspension)
    
                # skip this data
                continue
            if row_year in years:
                years[row_year] = years[row_year] + 1
            else:
                years[row_year] = 1
        print(years)    
    
    with open("nfl_suspensions_data.csv") as file:
        nfl_suspensions = list(csv.reader(file))[1:]
    
    your_code_fixed(nfl_suspensions)
    

    以上数据文件的输出:

    Data corrupt: less then 6 entries. Line: 21
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 33
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 41
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 48
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 54
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 59
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 63
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 67
    ['na', 'na', 'na', 'na']
    Data corrupt: less then 6 entries. Line: 71
    ['na', 'na', 'na', 'na']
    
    {'1981': 1, '1982': 2, '1983': 2, '1984': 3, '1985': 2, '1986': 4, '1987': 2,
     '1988': 4, '1989': 3, '1990': 3, '1991': 1, '1992': 5, '1993': 1, '1994': 3, 
     '1995': 3, '1996': 4, '1997': 1, '1998': 5, '1999': 1, '2000': 4, '1980': 8}
    

    【讨论】:

    • 这很有用!但它仍然让我感到困惑,它可以在教程网站上运行,但会在我的计算机上吐出 IndexError
    • @AkanoBenjamin 查看包含错误文件的工作示例。您的演示文件可能有一个尾随换行符或类似的东西 - 检查它。网站上的文件有正确的数据
    猜你喜欢
    • 2019-09-15
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    相关资源
    最近更新 更多