如何使用标记元素拆分列表?

发布于 2025-02-07 08:45:36 字数 988 浏览 2 评论 0 原文

我正在尝试使用一些元素作为标记在Python中划分列表。例如,请考虑列表:

["marker1", "elem1", "elem2", "marker2", "elem3"]

我希望将其分为2个子列表:

[["marker1", "elem1", "elem2"], ["marker2", "elem3"]]

如果第一个元素不是标记,则将标记之前的元素视为单独的sublist:

# From:
["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5"]
# To:
[["elem1", "elem2"], ["marker1", "elem3"], ["marker2", "elem4", "elem5"]]

使用常规循环很容易执行:

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5"]

separated = []
sub_lst = []
for elem in lst:
    if elem[:6] == "marker" and sub_lst:
        separated.append(sub_lst)
        sub_lst = []
    sub_lst.append(elem)
if sub_lst:
    separated.append(sub_lst)

此代码 很容易长9行。我的问题是如何使用列表理解或任何其他功能样式在一行(左右)中执行此操作。也欢迎其他任何优雅的解决方案。

I'm trying to split a list in Python using some elements as markers. For example, consider the list:

["marker1", "elem1", "elem2", "marker2", "elem3"]

I wish to split it into 2 sublists:

[["marker1", "elem1", "elem2"], ["marker2", "elem3"]]

If the first element is not a marker, the elements before the marker shall be considered as a separate sublist:

# From:
["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5"]
# To:
[["elem1", "elem2"], ["marker1", "elem3"], ["marker2", "elem4", "elem5"]]

It is easy to do using a regular loop:

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5"]

separated = []
sub_lst = []
for elem in lst:
    if elem[:6] == "marker" and sub_lst:
        separated.append(sub_lst)
        sub_lst = []
    sub_lst.append(elem)
if sub_lst:
    separated.append(sub_lst)

This code is 9 lines long. My question is how to do that in one line (or so) using list comprehension or any other functional style. Any other elegant solutions are welcome as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟织青萝梦 2025-02-14 08:45:36

在开始或标记处创建(并包含)一个新的内部列表,否则将附加到当前的内部列表(< DMSULPOPUQTXHVZ7LM2FEUH@3DBF29/@dmuzsfijmmodcywyzyqcccccccccccccc3xrhx28M5IUH5Y0GMQMQAQMAEEZVDNGGEVDNGEVDNGEVDNGEV6BKNYYY2FYWUBD9JHZLGFV/7MIBLBCRBCRBCRBCRBCRBCRBCRBCR // avnxg“ rel =” nofollow noreferrer“ title =” python 3.8(预释放) - 在线尝试”>在线尝试!):

a = None
separated = [a := [x] for x in lst if not a or x.startswith('marker') or a.append(x)]

另一个(Try it online!):

separated = [
    a
    for a in [None]
    for x in lst
    if not a or x.startswith('marker') or a.append(x)
    for a in [[x]]
]

Yet another (未经测试,现在无法测试):

from more_itertools import split_before

separated = list(split_before(lst, lambda s: s.startswith('marker')))

Create (and include) a new inner list at the start or at a marker, otherwise append to the current inner list (Try it online!):

a = None
separated = [a := [x] for x in lst if not a or x.startswith('marker') or a.append(x)]

Another (Try it online!):

separated = [
    a
    for a in [None]
    for x in lst
    if not a or x.startswith('marker') or a.append(x)
    for a in [[x]]
]

Yet another (untested, can't test now):

from more_itertools import split_before

separated = list(split_before(lst, lambda s: s.startswith('marker')))
尬尬 2025-02-14 08:45:36

您可以查找列表中标记元素的索引,然后根据这些位置进行订书机:

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5"]
idxs = [i for i, v in enumerate(lst) if type(v) == str and v.startswith('marker')]
separated = [lst[i:j] for i, j in zip([0]+idxs, idxs+[len(lst)]) if i < j]
# [['elem1', 'elem2'], ['marker1', 'elem3'], ['marker2', 'elem4', 'elem5']]

lst = ["marker1", "elem1", "elem2", "marker2", "elem3"]
idxs = [i for i, v in enumerate(lst) if type(v) == str and v.startswith('marker')]
separated = [lst[i:j] for i, j in zip([0]+idxs, idxs+[len(lst)]) if i < j]
# [['marker1', 'elem1', 'elem2'], ['marker2', 'elem3']]

这个答案

You could look up the indexes of the marker elements in the list, and then take sublists based on those positions:

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5"]
idxs = [i for i, v in enumerate(lst) if type(v) == str and v.startswith('marker')]
separated = [lst[i:j] for i, j in zip([0]+idxs, idxs+[len(lst)]) if i < j]
# [['elem1', 'elem2'], ['marker1', 'elem3'], ['marker2', 'elem4', 'elem5']]

lst = ["marker1", "elem1", "elem2", "marker2", "elem3"]
idxs = [i for i, v in enumerate(lst) if type(v) == str and v.startswith('marker')]
separated = [lst[i:j] for i, j in zip([0]+idxs, idxs+[len(lst)]) if i < j]
# [['marker1', 'elem1', 'elem2'], ['marker2', 'elem3']]

Adapted from this answer.

我ぃ本無心為│何有愛 2025-02-14 08:45:36

这就是 i 看起来像 [['elem1','elem2'],['marker1'],['elem3'],['marker2'],['elem4', 'elem5'],['marker3'],['elem6','elem7']] ,但是在发电机中

,我们使用 zip i i AS Generator 要将每个2个列表组合在一起 ['Elem1','Elem2'] + ['Marker1']

from itertools import groupby

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5", "marker3", "elem6", "elem7"]

i = (list(g) for _, g in groupby(lst, key=lambda x: x.startswith('marker')))

print([a + b for a, b in zip(i, i)])

edit1

from itertools import groupby, zip_longest

lst = ["marker0", "elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5", "marker3", "elem6", "elem7"]

i = (list(g) for _, g in groupby(lst, key=lambda x: x.startswith('marker')))

print([a + b for a, b in zip_longest(i, i, fillvalue=[])])

edit2

from itertools import groupby, zip_longest

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5", "marker3", "elem6", "elem7"]

i = iter([[]] + [list(g) for _, g in groupby(lst, key=lambda x: x.startswith('marker'))])

print([a + b for a, b in zip_longest(i, i, fillvalue=[])])

this is how i look like [['elem1', 'elem2'],['marker1'],['elem3'],['marker2'],['elem4', 'elem5'],['marker3'],['elem6', 'elem7']] but in a generator ofcourse

so we use zip and i as generator to compine every 2 lists together ['elem1', 'elem2'] + ['marker1']

from itertools import groupby

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5", "marker3", "elem6", "elem7"]

i = (list(g) for _, g in groupby(lst, key=lambda x: x.startswith('marker')))

print([a + b for a, b in zip(i, i)])

Edit1

from itertools import groupby, zip_longest

lst = ["marker0", "elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5", "marker3", "elem6", "elem7"]

i = (list(g) for _, g in groupby(lst, key=lambda x: x.startswith('marker')))

print([a + b for a, b in zip_longest(i, i, fillvalue=[])])

Edit2

from itertools import groupby, zip_longest

lst = ["elem1", "elem2", "marker1", "elem3", "marker2", "elem4", "elem5", "marker3", "elem6", "elem7"]

i = iter([[]] + [list(g) for _, g in groupby(lst, key=lambda x: x.startswith('marker'))])

print([a + b for a, b in zip_longest(i, i, fillvalue=[])])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文