如何按指定元素的出现位置分割Python列表?
按指定元素分割Python列表(不含分隔符)
嘿,这个需求我之前也碰到过,你的思路方向完全没问题,用itertools.groupby确实是高效的解法,不过咱们可以优化一下,不用分两步处理~
优化你的现有解法
你当前先用groupby分组,再过滤含0的子列表,其实可以在分组的同时就完成过滤,一步到位:
import itertools as it import operator as op from functools import partial import random as rnd # 生成原列表 lst = [x for x in it.islice(it.cycle(range(1,10)), 50)] idx = set(rnd.sample(range(len(lst)), 10)) for i in idx: lst.insert(i, 0) # 一步生成不含0的分割子列表 new_lst = [list(g) for k, g in it.groupby(lst, partial(op.eq, 0)) if not k]
原理说明
groupby的第一个返回值k是分组的判断结果:我们用partial(op.eq, 0)作为分组函数,当元素等于0时,k为True,对应全是0的分组;非0元素的分组k为False。所以在列表推导式里加上if not k,直接跳过所有0的分组,不用再二次过滤。
如果觉得partial和operator有点绕,换成lambda表达式可读性会更高:
new_lst = [list(g) for k, g in it.groupby(lst, lambda x: x == 0) if not k]
这样不用额外导入operator和functools,代码更简洁直观。
另一种思路:手动记录切片位置
如果你想更底层地控制分割过程,也可以手动遍历列表记录分割点,避免生成中间的0分组:
new_lst = [] start_idx = 0 for idx, val in enumerate(lst): if val == 0: # 避免连续0导致生成空列表 if start_idx < idx: new_lst.append(lst[start_idx:idx]) start_idx = idx + 1 # 处理列表末尾最后一段非0元素 if start_idx < len(lst): new_lst.append(lst[start_idx:])
这个方法和groupby效率差不多,但可以直观看到每一步的分割逻辑,适合需要自定义分割规则的场景(比如处理连续分隔符的情况)。
验证结果
不管用哪种方法,最终得到的new_lst都会是被0分隔、且完全不含0的子列表,比如类似这样的结构:
[[1, 2, 3, 4], [5, 6, 7, 8, 9], [1, 2], [3, 4], [5], [6, 7, 8], ...]
内容的提问来源于stack exchange,提问作者NarūnasK
相关产品推荐
相关产品推荐

