繁体   English   中英

Python-从一个文件读取数据并有选择地写入新文件

[英]Python - reading data from one file and selectively writing to a new file

在此先感谢您的帮助。

我是新的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:列表索引超出范围

行拆分分解了八列数据,我想删除其中的前两列。 因此,最终,我要重写的是整个文件减去前两列。 我需要做一些更复杂的重新格式化,但是我希望如果我能理解此步骤中的错误,我可能会想出其余的方法。

--------------更新

abarnet,你是​​对的。 导致错误的是换行符。 然而,尝试添加检查时,就像你说的,我有另外一个问题。 当我执行下面的代码时,一切都冻结在我身上。 如果删除了“ if data:”检查,则它会运行,但会给我同样的“索引超出范围”错误。

我还尝试了如下操作,删除了“ 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()

首先,如果line空会怎样?

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

只需移动if not line: break首先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周围循环readline ,只是当它到达EOF,循环自动没有你需要测试任何东西或结束break

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')在第一种情况下,当线已经处于结束\\n所以你只需添加额外的换行符,但随后fnew.write(data[0])在其他情况下,当data[0]不换行结束了,所以你只是合并第一列的运行连成一个巨大的字与上涨到年底的下一个评论...


与你的新代码的问题是,而不是替换 while True:环周围readline()for line in f:环,你有两个

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

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

  • fs.close只是引用方法,而不实际调用它。 你需要括号的电话,像fs.close()
  • 但是,你不想fs.close()反正; with语句的全部要点是它将自动关闭文件。
  • 您可能还希望对fnew使用with语句。

所以:

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')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM