【问题标题】:How to split a list on an element delimiter [duplicate]如何在元素分隔符上拆分列表[重复]
【发布时间】:2018-05-19 14:50:03
【问题描述】:

有没有简洁优雅的方式通过分隔元素将 Python 中的列表拆分为子列表列表,例如 ['a', 'delim', 'b'] -> [['a'], ['b']]

示例如下:

ldat = ['a','b','c','a','b','c','a','b']
dlim = 'c'
lspl = []   # an elegant python one-liner wanted on this line!
print(lspl) # want: [['a', 'b'], ['a', 'b'], ['a', 'b']]

看似过于复杂的工作示例

我已经调查了有关 stackoverflow 的文档和相关问题 - 下面引用了许多 - 没有回答我的问题,我在下面总结了我的研究:确实生成所需输出但很冗长的几种方法并且错综复杂,并且正在发生的事情(拆分列表)并不是很明显 - 你真的必须眯着眼睛。

有没有更好的方法?我主要对初学者的可读性(例如教学)、规范/“Pythonic”方法感兴趣,其次对最有效的方法(例如 timeit 速度)感兴趣。理想情况下,答案将同时针对 Python 2.7 和 3.x。

有条件的.append()

遍历列表并追加到最后一个输出列表或添加新的输出列表。基于 includes the delimiter 的示例,但已更改为排除它。我不知道如何使它成为一个单线,或者这是否是可取的。

lspl = [[]]
for i in ldat:
    if i==dlim:
        lspl.append([])
    else:
        lspl[-1].append(i)
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]

使用 itertools.groupby

将 itertools.groupby 与列表理解相结合。很多答案include delimeters,这是基于exclude delimeters的答案。

import itertools
lspl = [list(y) for x, y in itertools.groupby(ldat, lambda z: z == dlim) if not x]
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]

对索引进行切片

一些相关问题已经讨论了在使用 .index() 之后如何使用切片——但是答案通常集中在查找 first index only 上。可以先通过finding a list of indices 扩展此方法,然后循环遍历自压缩列表以分割范围。

indices = [i for i, x in enumerate(ldat) if x == dlim]
lspl = [ldat[s+1:e] for s, e in zip([-1] + indices, indices + [len(ldat)])]
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]

但是,就像我发现的所有方法一样,这似乎是一种非常复杂的方式来执行简单的分隔符拆分操作。

与字符串拆分的比较

相比之下,仅作为模型,这是一种有效、简洁且优雅的拆分方式 通过分隔符将字符串转换为子字符串列表。

sdat = 'abcabcab'
dlim = 'c'
sspl = sdat.split(dlim)
print(sspl) # prints: ['ab', 'ab', 'ab']

注意:我知道 Python 中的列表上没有 split 方法,我不是在询问拆分字符串的问题。我也不是在询问将元素字符串拆分为新元素。

【问题讨论】:

  • 我想到了对索引进行切片的方法,尽管那是两行。将它包装在一个函数中:) 然后它是一行
  • “我不知道如何使它成为一个单线,或者如果这甚至是可取的。”不,它本身不是。真的,没有比 for 循环更规范的了。事实上,我看到您编写第一个示例的最大问题是将ifelse 正文放在一行 - 使用缩进。
  • 分隔符在开始或结束时的预期行为?
  • 真的任何行为都很好。所以['delim', 'a', 'b', 'delim'] 可以变成[['a'], ['b']],或[[], ['a'], ['b'], []],甚至[['a'], ['b'], []][[], ['a'], ['b']]

标签: python list split


【解决方案1】:

或者这个:

ldat = ['a','b','c','a','b','c','a','b']
dlim = 'c'
lspl = []   # an elegant python one-liner wanted on this line!
print(lspl) # want: [['a', 'b'], ['a', 'b'], ['a', 'b']]

s = str(ldat).replace(", '%s', " % dlim, "],[")
result = eval(s)
print(result)

【讨论】:

猜你喜欢
  • 2020-06-08
  • 2022-01-19
  • 2020-06-10
  • 2018-12-08
  • 2018-03-12
  • 2020-01-05
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多