Python I / O索引超出范围,而不是一个一个错误(我认为)

时间:2012-07-20 21:13:18

标签: python io

我有这个简单的代码,这只是为了帮助我理解Python I / O的工作原理:

inFile = open("inFile.txt",'r')
outFile = open("outFile.txt",'w')
lines = inFile.readlines()

first = True
for line in lines:
    if first == True:
        outFile.write(line)  #always print the header
        first = False
        continue
    nums = line.split()
    outFile.write(nums[3] + "\n") #print the 4th column of each row
outFile.close()

我的输入文件是这样的:

#header
34.2 3.42 64.56 54.43 3.45
4.53 65.6 5.743 34.52 56.4
4.53 90.8 53.45 134.5 4.58
5.76 53.9 89.43 54.33 3.45

输出打印到文件中,但我也得到错误:

    outFile.write(nums[3] + "\n")
IndexError: list index out of range 

我假设这是因为它已经继续阅读下一行,虽然不再有任何数据?

3 个答案:

答案 0 :(得分:2)

错误显示您的源代码中包含以下行:

outFile.write(nums[6] + "\n")  

请注意,6与您在问题中显示的3不同。您可能有两个不同版本的文件。

失败是因为nums是拆分行的结果,在你的情况下它只包含5个元素:

for line in lines:
    # ...
    # line is for example "34.2 3.42 64.56 54.43 3.45"
    nums = line.split() 
    print len(nums)

您无法索引列表的末尾。

您的代码中也可能出错。你编写标题,然后拆分它并从中写入一个元素。你可能想要一个if / else。

for line in lines:
    if first == 1: 
        # do something with the header
    else:
        # do something with the other lines

或者你可以在进入循环之前单独处理标题。

答案 1 :(得分:2)

其他人已经回答了你的问题。以下是“始终打印文件头”的更好方法,避免在每次迭代时测试first

with open('inFile.txt', 'r') as inFile, open('outFile.txt', 'w') as outFile:
    outFile.write(inFile.readline()) #always print the header
    for line in inFile:
        nums = line.split()
        if len(nums) >= 4: #Checks to make sure a fourth column exists.
            outFile.write(nums[3] + "\n") #print the 4th column of each row

有几件事情在这里发生:

with open('inFile.txt', 'r') as inFile, open('outFile.txt', 'w') as outFile:

with表达式是一种打开文件的便捷方式,因为它会自动关闭文件,即使发生异常并且with block也会提前退出。

注意:在Python 2.6中,您需要使用两个with语句,因为直到2.7才添加对多个上下文的支持。 e.g:

with open(somefile, 'r') as f:
    with open(someotherfile, 'w') as g:
        #code here.

outFile.write(inFile.readline()) #always print the header

file对象是一个获取消耗的迭代器。调用readline()时,缓冲区位置向前推进,返回第一行。


for line in inFile:

如前所述,file对象是一个迭代器,因此您可以直接在for循环中使用它。

答案 2 :(得分:1)

问题在于您正在处理“标题行”,就像其他数据一样。即,即使您确定标题行,您也不会跳过它的处理。即,您不会在循环中进一步避免split()进一步导致运行时错误。

要解决您的问题,只需插入continue,如下所示:

first = True
for line in lines:
    if first == True:
       outFile.write(line)  #always print the header
       first = False
       continue   ## skip the rest of the loop and start from the top 
    nums = line.split()
    ...

将绕过循环的其余部分,所有这些都将按预期工作。

输出文件outFile.txt将包含:

#header
54.43
34.52
134.5
54.33

第二个问题是输入文件末尾有空行(见下面评论中的讨论)

备注:您可以重新构建代码,但如果您对此不感兴趣,上面的简单修复可让您保留所有现有代码,并且只需要添加一行代码。正如其他帖子中所提到的,值得研究使用with来管理您的打开文件,因为它会在您完成或遇到异常时为您关闭它们。