当子列表的大小依赖于数据值(种子和扩展)时,将列表拆分为子列表

时间:2017-01-26 12:46:32

标签: python

我有一个列表,其中标题以"Header"字符串开头,并且对应 与标题关联的数据在列表中连续跟随它,以下一个"Header"前缀元素结束:

data = ["Header: 1",
        "Some info 1",
        "Some info 2",
        "Some info 3",
        "Header: 2",
        "Some info 4",
        "Header: 3",
        "Some info 5",
        "Some info 6",
        ]
len(data) # returns 9

我想在标题间隔拆分列表,以创建标题数据元素列表 - 它是经典种子并扩展。所以最终目标是:

entries = [ ["Header: 1",
        "Some info 1",
        "Some info 2",
        "Some info 3"],
        ["Header: 2",
        "Some info 4"],
        ["Header: 3",
        "Some info 5",
        "Some info 6"]
        ]
 len(data) # returns 3

与每个标题关联的数据元素的数量是可变的。 因为每个标题都以"Header"开头,所以我可以使用它来确定 间隔。 我可以使用循环来解决:

entries = []
for i in range(0,len(data)):
    if "Header" in data[i]:
        entry = []
        entry.append(data[i])
        i = i + 1
        while("Header" not in data[i]):
            entry.append(data[i])
            i = i + 1
            if i == len(data):
                break
        entries.append(entry)

然而,我想知道是否有一个衬垫(或接近的东西)可以做到这一点? 也许是列表理解方法。我不熟悉python库,但是标准库的解决方案也没问题。

3 个答案:

答案 0 :(得分:3)

在我看来,更优雅的方法是:

entries = []
entry = None
for element in data:
    if element.startswith('Header'): #or 'Header' in element if it can be everywhere
        entry = []
        entries.append(entry)
    entry.append(element)

这里你迭代element中的data。您检查"Header"中是否有element,我们找到了新的“记录”,我们构建了一个没有元素的entry列表(作为初始记录)并添加{{1}到entry。无论如何,我们会将entries添加到当前的element记录中。

运行此命令:

entry

或在Python2中:

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> data = ["Header: 1", \
...         "Some info 1", \
...         "Some info 2", \
...         "Some info 3",\
...         "Header: 2",\
...         "Some info 4",\
...         "Header: 3", \
...         "Some info 5",\
...         "Some info 6",\
...         ]
>>> 
>>> entries = []
>>> entry = None
>>> for element in data:
...     if "Header" in element:
...         entry = []
...         entries.append(entry)
...     entry.append(element)
... 
>>> entries
[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2', 'Some info 4'], ['Header: 3', 'Some info 5', 'Some info 6']]

答案 1 :(得分:3)

您可以使用itertools.groupby,并按"不以Header"开头。对元素强制列表迭代:

l = [list(x) for a,x in itertools.groupby(data,lambda x : not x.startswith("Header"))]

现在l[['Header: 1'], ['Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2'], ['Some info 4'], ['Header: 3'], ['Some info 5', 'Some info 6']]

然后将项目2分组2:

result = [l[i]+l[i+1] for i in range(0,len(l),2)]

结果:

[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'], ['Header: 2', 'Some info 4'], ['Header: 3', 'Some info 5', 'Some info 6']]

注意:如果有空信息块

,则不起作用

答案 2 :(得分:2)

以下代码会在子列表中展开您的列表,然后根据需要合并子列表。

from itertools import groupby

splode = [list(g) for k,g in groupby(data, key=lambda x: x.startswith('Header'))]
merged = [h+i for h,i in zip(splode[::2],splode[1::2])]

> merged   # output is:
#[['Header: 1', 'Some info 1', 'Some info 2', 'Some info 3'],
# ['Header: 2', 'Some info 4'],
# ['Header: 3', 'Some info 5', 'Some info 6']]