说我有一个清单:
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:]
我可以很容易地编写一个执行此操作的函数,但我想知道是否可以在一个表达式中执行此操作。
答案 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.itemgetter
与slice
个对象一起使用:
>>> 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)
从您的列表开始:
>>> 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]]