谁能解释这个索引的根超出范围错误?

Mis*_*ing 5 python list range

以下代码引发了一个我无法找到解决方案的神秘错误.当我在一个更大的模块中测试它时它工作正常,所以无法理解为什么这不起作用:

import csv

with open('studentinfo.txt','a') as fo: #open the file in append mode (add to file, we don't wish to overwrite!)
        studentfileWriter=csv.writer(fo) #fo = file out (this can be called anything you like)
        id=input("Enter Student Id:")
        firstname=input("Enter firstname:")
        surname=input("Enter Surname:")
        test1=input("Enter test1 score:")
        test2=input("Enter test2 score:")
        test3=input("Enter test3 score:")
        studentfileWriter.writerow([id,firstname,surname,"Test1:"+test1,"Test2:"+test2,"Test3:"+test3])
        print("Record has been written to file")


with open("studentinfo.txt", "r") as f:
    reader = csv.reader(f)
    sorted_list = list(reader)  # turn the reader iterator into a list
    sorted_list.sort(key=lambda x: x[2])  # use the third column as a sorting key
    print("\n".join(str(row) for row in sorted_list))  # prettier print
Run Code Online (Sandbox Code Playgroud)

错误信息

sorted_list.sort(key=lambda x: x[2])  # use the third column as a sorting key
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)

值得注意的是,当没有添加文件内容时,代码工作正常.在将学生添加到文件时,SORT不起作用.

原始文件内容

001,Joe,Bloggs,Test1:99,Test2:100,Test3:1
002,Ash,Smith,Test1:20,Test2:20,Test3:100
003,Jonathan,Peter,Test1:99,Test2:33,Test3:44
Run Code Online (Sandbox Code Playgroud)

添加测试学生的文件内容:

001,Joe,Bloggs,Test1:99,Test2:100,Test3:1
002,Ash,Smith,Test1:20,Test2:20,Test3:100
003,Jonathan,Peter,Test1:99,Test2:33,Test3:44
006,Mulch,Cart,Test1:99,Test2:22,Test3:11
Run Code Online (Sandbox Code Playgroud)

结果错误发生在此阶段(添加新学生时).否则排序功能正常.

更新和澄清:

出于教学目的,我需要它在repl.it和IDLE>上工作

如果有人可以发布一个repl.it作为答案(使用上面的代码,工作),这也可以在IDLE中使用txt文件实现时,我会接受作为答案.

Jea*_*bre 6

你在这里问题的原因是你没有csv正确追加.

在Windows上,csv运行Windows时模块存在错误/限制.如果你没有正确打开文件,它会在每一行添加额外的空行(实际上它会添加一个额外的回车符).所以解决它:

Python 3:

with open('studentinfo.txt','a',newline='') as fo:
Run Code Online (Sandbox Code Playgroud)

Python 2:

with open('studentinfo.txt','ab') as fo:
Run Code Online (Sandbox Code Playgroud)

所以csv模块\r在文件末尾添加一个额外的.当再次阅读它时,它会发出一个空行.

它在repl.it中工作正常,因为它们使用的是在Linux沙箱上运行的python引擎),但是文档仍然建议打开像我所示的文件.

(csv模块的文档清楚地说明了这一点,即使它建议在读取模式下也这样做,我从来没有遇到任何简单的问题open("file.csv"))

另请参阅我的一个老问题:在python 2或python 3中编写csv文件的便携方式

如果文件末尾有一个双回车符,则表示您没有看到它(使用带有"显示所有符号"的Notepad ++来查看双CRCR字符)但csv.reader返回一个空行,当sort使用您的键功能进行比较时,该行失败它.

现在,如果你想要坚强(因为其他人可以编辑你的数据库,例如,使用excel csv模式或其他可怕的东西):

我会过滤掉&sort并转换为list同时使用filter(None,...)删除"falsy"(即空)行:

sorted_list = sorted(filter(None,reader),key=lambda x: x[2])
Run Code Online (Sandbox Code Playgroud)

当然,如果一行只有1或2个项目,那么也会失败.在那种情况下,filter因为我们必须写一个lambda并且它不值得,因为支持生成器理解:

sorted_list = sorted((x for x in reader if len(x)>2),key=lambda x: x[2])
Run Code Online (Sandbox Code Playgroud)