0

我有这个简单的代码,它实际上只是为了帮助我理解 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 

我假设这是因为它继续读取下一行,尽管不再有任何数据?

4

3 回答 3

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

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

于 2012-07-20T21:14:56.387 回答
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 块提前退出,它也会自动关闭文件。

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

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循环中使用它。

于 2012-07-20T21:30:16.467 回答
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来管理您打开的文件,因为它也会在您完成或遇到异常时为您关闭它们。

于 2012-07-20T21:15:19.170 回答