以下代码引发了一个我无法找到解决方案的神秘错误.当我在一个更大的模块中测试它时它工作正常,所以无法理解为什么这不起作用:
码
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文件实现时,我会接受作为答案.
你在这里问题的原因是你没有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)