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

时间:2017-07-20 18:51:58

标签: python list range

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

代码

class A
  include Mod
  def foo(x)
    super(x) + 1
  end
end
A.new.foo(5) == 26 # true

class A
  include Mod2
end
A.new.foo(5) == 11 # true

class A
  include Mod
end
A.new.foo(5) == 11

错误消息

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

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

原始文件内容

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

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

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

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

更新和澄清:

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

上工作

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

1 个答案:

答案 0 :(得分:6)

您在此处遇到问题的原因是您没有正确追加csv

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

Python 3:

with open('studentinfo.txt','a',newline='') as fo:

Python 2:

with open('studentinfo.txt','ab') as fo:

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

它在repl.it中运行正常,因为它们使用的是在Linux沙箱上运行的python引擎),但documentation仍然建议打开我已经显示的文件。

csv模块的文档对此很清楚,即使它建议在读取模式下也这样做,并且我从来没有遇到任何简单open("file.csv")的问题

另见我的一个老问题:portable way to write csv file in python 2 or python 3

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

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

我会过滤掉&排序&使用filter(None,...)同时转换为列表,删除“falsy”(即空)行:

sorted_list = sorted(filter(None,reader),key=lambda x: x[2])

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

sorted_list = sorted((x for x in reader if len(x)>2),key=lambda x: x[2])