如何在python中同时执行多个列表切片

时间:2015-11-13 23:25:13

标签: python slice

说我有一个清单:

L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

我有一个索引列表:

indices = (2, 5, 7)

我希望能够做的是同时在所有3个索引处切割列表。换句话说,id喜欢在一行中执行以下代码行:

sub1 = L1[:2]
sub2 = L1[2:5]
sub3 = L1[5:7]
sub4 = L1[7:]

我可以很容易地编写一个执行此操作的函数,但我想知道是否可以在一个表达式中执行此操作。

5 个答案:

答案 0 :(得分:4)

你在找一个班轮吗?我们可以给你一个,但我会保持简单:

L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
indices = (2, 5, 7)

start = 0
sections = []
for end in indices:
    sections.append(L1[start:end])
    start = end
sections.append(L1[start:])

for part in sections:
    print part
# [1, 2]
# [3, 4, 5]
# [6, 7]
# [8, 9]

答案 1 :(得分:3)

您可以将operator.itemgetterslice个对象一起使用:

>>> from operator import itemgetter
>>> get = itemgetter(slice(0, 2), slice(2, 5), slice(5, 7), slice(7, None))

>>> values = range(1, 10)
>>> values
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> get(values)
([1, 2], [3, 4, 5], [6, 7], [8, 9])

答案 2 :(得分:2)

是的,它可以在一个表达式中完成,但它不是非常易读:

seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
ind = (2, 5, 7)
print([seq[p:q] for p,q in zip((0,)+ind, ind+(len(seq),))])

<强>输出

[[1, 2], [3, 4, 5], [6, 7], [8, 9]]


如果您确实要将子列表分配给不同的名称,可以这样做:

s1, s2, s3, s4 = [seq[p:q] for p,q in zip((0,)+ind, ind+(len(seq),))]

但将它们保存在列表列表中可能更好。

答案 3 :(得分:0)

嗯,借助一些内置功能,您可以在一行中完成。 “最大”的问题是将端点列表转换为(start,end)元组或slice个对象的列表。

下面的代码扩展了endpoints列表,一端为0,另一端为None,并使用zip()组合它们。然后使用operator.itemgetter()技巧提取切片:

import operator
ends = [2,5,7]
values = range(20)

operator.itemgetter(*[slice(*z) for z in zip([0]+ends, ends+[None])])(values)

输出:

([0, 1], [2, 3, 4], [5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])

答案 4 :(得分:0)

List comprehensions太棒了。

从您的列表开始:

>>> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

使用None填充您的索引:

>>> indices = (None, 2, 5, 7, None)

现在理解了:

>>> [L1[start:stop] for start, stop in zip(indices[:-1], indices[1:])]
[[1, 2], [3, 4, 5], [6, 7], [8, 9]]