0

在此先感谢您的帮助。

我是 Python 新手,正在尝试将文件从一种格式转换为另一种格式。

这是我的代码:

fs = open('sample_data.txt','r')
fnew = open('sample_output.txt','w')
with fs as f:
    while True:
        line = f.readline()
        if line and line[0]=='#':
            print(line)
            fnew.write(line + '\n')
        else:
            data=line.split()
            fnew.write(data[0])
        if not line:  break

print('end of program')
fs.close
fnew.close

文件的基本格式在顶部包含注释的标题,然后是数据行。

我遇到的问题是我的 fnew.write(data[0]) 行。我收到以下错误:

IndexError:列表索引超出范围

行拆分分解了八列数据,我想删除其中的前两列。所以,最终,我想要做的是重写整个文件减去前两列。我需要做一些更复杂的重新格式化,但我希望如果我能理解这一步中的错误,我可能会弄清楚如何做剩下的。

- - - - - - - 更新

阿巴内特,你是对的。这是导致错误的换行符。但是,正如您所说,在尝试添加支票时我遇到了另一个问题。当我执行下面的代码时,一切都冻结了我。如果我删除“如果数据:”检查,那么它会运行但给我同样的“索引超出范围”错误。

我还尝试在删除“if data:”检查的情况下运行它,并使用不包含换行符的示例数据文件,它也会冻结在我身上。

任何人都可以阐明可能导致这种情况的原因吗?

fs = open('sample_data.txt','r')
fnew = open('sample_output.txt','w')
with fs as f:
    while True:
        line = f.readline()
        for line in f:
            if line[0]=='#':
                print(line)
                fnew.write(line + '\n')
            else:
                data=line.split()
                if data:
                    print(data[0])
                    fnew.write(data[0] + '\n')

print('end of program')
fs.close
fnew.close

-------------- 更新 2

下面的代码有效。感谢 abarnet 澄清无限循环问题。我遇到的最后一个问题是数据的第一行,无论是换行符还是标题行都被忽略并且不会在输出中打印。

with open('sample_data.txt','r') as f, open('sample_output.txt','w') as fnew:
    line = f.readline()
    for line in f:
        if line[0]=='#':
            print(line)
            fnew.write(line + '\n')
        else:
            data=line.split()
            if data:
                print(data[0])
                fnew.write(data[0] + '\n')

print('end of program')
fnew.close()
4

1 回答 1

1

首先,如果line是空的会发生什么?

你最终会到达if not line: break. 但在你到达那里之前,你会到达第一个else:(因为这不是真的line and line[0]=='#')。所以,你的data = line.split()意志给你data = []。然后data[0]会提出一个IndexError.

只需if not line: break先移动测试:

while True:
    line = f.readline()
    if not line:
        break
    elif line[0]=='#':
        print(line)
        fnew.write(line + '\n')
    else:
        data=line.split()
        fnew.write(data[0])

话虽如此,首先有一个更简单的方法来编写它。循环遍历文件将为您逐行提供每一行,就像while围绕.readlinebreak

for line in f:
    if line[0]=='#':
        print(line)
        fnew.write(line + '\n')
    else:
        data=line.split()
        fnew.write(data[0])

但是如果该行不为空,如果它只是空白,或者纯空格会发生什么?例如,当您调用时会发生split()什么' \n'?同样,您会得到一个空列表。因此,如果可能的话,您将再次遇到同样的问题——当然,在这种情况下您可能不想这样做break。我不确定您想做什么,但假设您只想跳过空白链接。所以只需else用这个替换块:

data=line.split()
if data:
    fnew.write(data[0])

作为旁注,fnew.write(line + '\n')在第一种情况下这样做很奇怪,行已经以 a 结尾,\n所以你只是添加一个额外的换行符,但fnew.write(data[0])在另一种情况下, wheredata[0]不以换行符结尾,所以你'只是将一系列第一列合并成一个大词,并在末尾添加下一条评论......</p>


您的新代码的问题在于,您没有用循环替换while True:循环,而是同时readline()拥有.for line in f:

因此,第一次通过while循环,它读取第一行,然后读取文件中的每一行,然后完成。然后,第二次通过while循环,它读取最后剩下的任何内容,然后读取所有剩余的 0 行,然后完成。它会一直持续下去,一遍又一遍地阅读最后的 0 行,直到时间结束,因为你永远不会break离开while True:.

您更新的代码中还有一些其他问题。

  • fs.close只是引用该方法,而不实际调用它。您需要括号来调用,例如fs.close().
  • 但无论如何你都不想要fs.close();该with语句的全部要点是它会自动关闭文件。
  • 您可能还想使用withfor 语句fnew

所以:

with open('sample_data.txt','r') as f, open('sample_output.txt','w') as fnew:
    for line in f:
        if line[0]=='#':
            print(line)
            fnew.write(line + '\n')
        else:
            data=line.split()
            if data:
                print(data[0])
                fnew.write(data[0] + '\n')

print('end of program')
于 2014-12-05T22:25:41.387 回答