如果给出以下列表lst
:
import random as rnd, operator as op, itertools as it
from functools import partial
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))]
new_lst
[[1, 2, 3, 4],
[0],
[5, 6, 7, 8, 9],
[0],
[1, 2],
[0],
[3, 4],
[0],
[5],
[0],
[6, 7, 8],
[0],
[9, 1, 2, 3, 4, 5, 6, 7],
[0],
[8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0],
[1, 2, 3, 4, 5, 6],
[0],
[7],
[0],
[8, 9, 1, 2, 3, 4, 5]]
注意结果new_lst
我仍然有分隔符,因此要实现期望的结果我必须再次迭代:
new_lst = [i for i in new_lst if 0 not in i]
new_lst
[[1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 2],
[3, 4],
[5],
[6, 7, 8],
[9, 1, 2, 3, 4, 5, 6, 7],
[8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6],
[7],
[8, 9, 1, 2, 3, 4, 5]]
有更有效的方法吗?
答案 0 :(得分:4)
只需在密钥k
上使用条件:
new_lst = [list(g) for k,g in it.groupby(lst, partial(op.eq, 0)) if not k]
或更直接,使用op.ne
:
new_lst = [list(g) for k,g in it.groupby(lst, partial(op.ne, 0)) if k]
或没有partial
(请注意0 .__ne__
中的空格,或使用(0).__ne__
):
new_lst = [list(g) for k,g in it.groupby(lst, 0 .__ne__) if k]
答案 1 :(得分:0)
你也可以尝试这个,它不使用任何库:
lst = [0, 1, 2, 3, 4, 0, 0, 5, 6, 0, 7, 8, 9, 10, 0, 0]
# indices of all zeroes
indexes = [-1] + [i for i, e in enumerate(lst) if e == 0]
# get all the sublists
result = []
for start, end in zip(indexes, indexes[1:]):
result.append(lst[start+1:end])
# add last if any
result.append(lst[end+1:])
# filter out empty lists
print([x for x in result if x])
哪个输出:
[[1, 2, 3, 4], [5, 6], [7, 8, 9, 10]]