我有一个文件如下:
>abc
AAA
AAA
>dfgg
BBBBB
BBBBB
BB
>zzz
CCCCC
CCC
我想要的输出是:
>abc
AAAAAA
>dfgg
BBBBBBBBBBBB
>zzz
CCCCCCCC
也就是把多行变成单行。
我写了下面的代码:
f = open('test.txt', 'r')
currentline = ""
for line in f:
if line.startswith('>'):
line = line.rstrip('\n')
print line
else:
line = line.rstrip('\n')
currentline = currentline + line
print currentline
f.close()
当然,这是不对的,因为 currentline 一直在增长直到结束。我不知道如何更新 currentline 并按指示打印输出。
我知道一种选择是使用 f.read() 或 f.readlines() 读取整个文件,并将文件视为字符串或列表,但作为该文件非常大,每一行不是以'>'开头的可以达到2000万个字符,我认为最好不要一次将整个文件读入内存并逐行处理。请让我知道您对此有何看法。
感谢您的帮助!
请您参考如下方法:
一个天真的解决方案:
from itertools import groupby
with open('data.txt') as f:
for key, group in groupby(f, lambda s: s.startswith('>')):
print(''.join(s.rstrip('\n') for s in group))
这仅适用于以 > 开头的行都是单行,它们在您的示例中。为了避免连接那些你可以做这样的事情:
from itertools import groupby, count
counter = count()
with open('data.txt') as f:
for key, group in groupby(f, lambda s: next(counter) if s.startswith('>') else -1):
print(''.join(s.rstrip('\n') for s in group))
关键是groupby的关键函数: count()是一个简单地生成整数序列 0、1、2 的生成器。这意味着每个 >行获得自己的唯一键,而所有其他行获得键 -1并且被组合在一起,除非 >线路介入。
事实上,可以使用任何保持组唯一性的表达式,它不一定是计数器。例如你可以使用这个:
lambda s: object() if s.startswith('>') else None
文件迭代和groupby都是惰性的,所以组将在读取组后的行后立即输出。
