如何通过项目的出现来切割Python列表?

时间:2018-02-01 12:33:56

标签: python python-3.x

如果给出以下列表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]]

有更有效的方法吗?

2 个答案:

答案 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]]