如何有效地将具有一定周期性的列表拆分为多个列表?

Posted

技术标签:

【中文标题】如何有效地将具有一定周期性的列表拆分为多个列表?【英文标题】:How to efficiently split a list that has a certain periodicity, into multiple lists? 【发布时间】:2022-01-19 07:57:04 【问题描述】:

例如原始列表:

['k','a','b','c','a','d','e','a','b','e','f','j','a','c','a','b']

我们希望将列表拆分为以'a' 开头和以'a' 结尾的列表,如下所示:

['a','b','c','a']

['a','d','e','a']

['a','b','e','f','j','a']

['a','c','a']

最终输出也可以是列表列表。我尝试了以'a' 为条件的双循环方法,但这效率低下且不是pythonic。

【问题讨论】:

请将您的代码编辑到您的问题中。 【参考方案1】:

你可以在一个循环中做到这一点:

lst = ['k','a','b','c','a','d','e','a','b','e','f','j','a','c','a','b']

out = [[]]
for i in lst:
    if i == 'a':
        out[-1].append(i)
        out.append([])
    out[-1].append(i)
out = out[1:] if out[-1][-1] == 'a' else out[1:-1]

也使用numpy.split:

out = [ary.tolist() + ['a'] for ary in np.split(lst, np.where(np.array(lst) == 'a')[0])[1:-1]]

输出:

[['a', 'b', 'c', 'a'], ['a', 'd', 'e', 'a'], ['a', 'b', 'e', 'f', 'j', 'a'], ['a', 'c', 'a']]

【讨论】:

【参考方案2】:

一种可能的解决方案是使用re(正则表达式)

import re

l = ['k','a','b','c','a','d','e','a','b','e','f','j','a','c','a','b']
r = [list(f"a_a") for _ in re.findall("(?<=a)[^a]+(?=a)", "".join(l))]
print(r)
# [['a', 'b', 'c', 'a'], ['a', 'd', 'e', 'a'], ['a', 'b', 'e', 'f', 'j', 'a'], ['a', 'c', 'a']]

【讨论】:

【参考方案3】:

首先,您可以从列表中存储'a' 的索引。

oList = ['k','a','b','c','a','d','e','a','b','e','f','j','a','c','a','b']

idx_a = list()

for idx, char in enumerate(oList):
    if char == 'a':
        idx_a.append(idx)

然后对于每个连续的索引,您可以获得子列表并将其存储在列表中

ans = [oList[idx_a[x]:idx_a[x + 1] + 1] for x in range(len(idx_a))]

如果您也采用中间索引,您还可以获得更多此类列表。

【讨论】:

【参考方案4】:

您可以通过一次迭代和一个简单的状态机来做到这一点:

original_list = list('kabcadeabefjacab')

multiple_lists = []
for c in original_list:
    if multiple_lists:
        multiple_lists[-1].append(c)
    if c == 'a':
        multiple_lists.append([c])
if multiple_lists[-1][-1] != 'a':
    multiple_lists.pop()

print(multiple_lists)
[['a', 'b', 'c', 'a'], ['a', 'd', 'e', 'a'], ['a', 'b', 'e', 'f', 'j', 'a'], ['a', 'c', 'a']]

【讨论】:

【参考方案5】:

我们可以使用str.split() 将列表拆分为一个字符串,然后将其str.join() 拆分为字符串,然后使用 f 字符串将剥离的“a”添加回。请注意,即使列表以“a”开头/结尾,此拆分列表也会有一个空字符串表示拆分之前的子字符串,因此我们丢弃第一个 + 最后一个子序列的解包逻辑仍将按预期工作。

def split(data):
    _, *subseqs, _ = "".join(data).split("a")
    return [list(f"aseqa") for seq in subseqs]

输出:

>>> from pprint import pprint
>>> testdata = ['k','a','b','c','a','d','e','a','b','e','f','j','a','c','a','b']
>>> pprint(split(testdata))
[['a', 'b', 'c', 'a'],
 ['a', 'd', 'e', 'a'],
 ['a', 'b', 'e', 'f', 'j', 'a'],
 ['a', 'c', 'a']]

【讨论】:

以上是关于如何有效地将具有一定周期性的列表拆分为多个列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将大型数据框拆分为多个拼花文件?

如何将可迭代拆分为两个具有交替元素的列表

R:具有多个标题的列表-如何按标题拆分(每个标题的行数不等)

如何更有效地将嵌套列表扁平化为一个列表而不是使用 unlist 方法?

有效地将不均匀的列表列表转换为用 nan 填充的最小包含数组

在 Angular 中,如何有效地将输入项拆分为数组