Python 3:如何根据条件拆分列表?

2024-09-24 08:38:12 发布

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

我已经找到了很多关于如何将列表分成大小相等的块的答案,但我有一个不同的问题

我有如下格式的数据

> header1
line1
line2
...
> header2
line4
line5
...

我想把这些行分组在各自的标题下

获取标题很容易headers = [x for x in lines if x.startswith('>')]

但这个技巧对后续的行不起作用,因为无法知道每个标题下有哪些行

理想情况下,我想要一个格式为[[line1, line2], [line4, line5]...]的列表

我有一个使用while循环的工作解决方案,但它看起来很难看。我如何使用列表理解或现有库来实现这一点


Tags: 数据答案in标题列表for格式headers
2条回答

itertools.groupby与自定义键函数一起使用,该函数在每次看到新头时都会更改。在这个函数中,我们增加ctr

from itertools import groupby

lis = ['>a', 'b', 'c', '>d', 'e', '>f', '>g']

def group_by_header(lis: list):
    def header_counter(x: str):
        if x.startswith('>'):
            header_counter.ctr += 1
        return header_counter.ctr
    header_counter.ctr = 0

    return groupby(lis, key=header_counter)

print([list(l) for k, l in group_by_header(lis)])
# [['>a', 'b', 'c'], ['>d', 'e'], ['>f'], ['>g']]

我的解决方案很可能不是最好的,但我们做到了:

样本数据:

data = """> header1
line1
line2
> header2
line4
line5
""".split("\n")

简单for循环解决方案OP提到:

def parse(d):
    result = []
    chunk = []
    for line in d:
        if not line:
            continue
        elif line.startswith(">"):
            if not chunk:
                continue
            result.append(chunk)
            chunk = []
            continue
        chunk.append(line)

    if chunk:
        result.append(chunk)
    
    return result

并通过索引头+使用索引(2行)切片阵列:

def _parse(d):
    index = [i for i in range(0, len(d)) if d[i].startswith(">")] + [len(d)-1]
    return [d[index[i]+1:index[i+1]]  for i in range(0, len(index)-1)]

两个[['line1', 'line2'], ['line4', 'line5']]的结果

相关问题 更多 >