Python中的多行到单行

2024-09-25 18:11:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个文件如下:

>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万个,我认为最好不要一次将整个文件读入内存并逐行处理。请告诉我你是怎么想的。

谢谢你的帮助!


Tags: 文件lineabcprintcccbbzzzaaa
3条回答

你的代码很好,你需要做的就是找到合适的地方来更新currentline。找到下一个标志后,您将进行更新,在您的示例中,下一个标志是以>开头的行。

f = open('test.txt', 'r')
currentline = ""
for line in f:
    if line.startswith('>'):
        line = line.rstrip('\n')
        if currentline != "": print currentline
        print line
        currentline = ""
    else:
        line = line.rstrip('\n')
        currentline = currentline + line
print currentline
f.close()


Input:

>abc
AAA
AAA
>dfgg
BBBBB
BBBBB
BB
>zzz
CCCCC
CCC

Output:

>abc
AAAAAA
>dfgg
BBBBBBBBBBBB
>zzz
CCCCCCCC

# edited code above and tested it with the below file based on ypnos's comment.
Input:

>abc
AAA
AAA
>dfgg
BBBBB
BBBBB
BB
>
>
>>
>zzz
CCCCC
CCC

Output:

>abc
AAAAAA
>dfgg
BBBBBBBBBBBB
>
>
>>
>zzz
CCCCCCCC

编辑:ypnos很好地指出,上面的代码会打印不必要的换行符。我对上面的代码做了一个小小的修改,它现在避免了打印这些代码。请参阅上面的新测试用例。

天真的解决方案:

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

关键是groupbycount()的键函数是一个生成器,它只生成一个整数序列0,1,2。这意味着每个>行都有自己的唯一键,而所有其他行都有一个-1键,并且除了>行介入时,它们被组合在一起。

实际上,任何保持组唯一的表达式都可以使用,不必是计数器。例如,您可以使用:

lambda s: object() if s.startswith('>') else None

文件迭代和groupby都是惰性的,因此组将在读取组后的行中立即输出。

一出现就打印所有内容的版本:

with open('test.txt', 'r') as f:
    flush = False
    for line in f:
        if line.startswith('>'):
            if flush:
                print('')
            print(line.rstrip('\n'))
            flush = False
        else:
            flush = True
            print(line.rstrip('\n'), end='')
    if flush:
        print('')

相关问题 更多 >