Python中复杂的列表切片/索引

8

我有一个类似于下面的列表:

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

我可以帮你进行翻译。需要生成一个过滤列表,具体形式如下:
filtered_lst = [2, 6, 7, 9, 10, 13]

Python提供了自定义切片的约定吗?类似于以下内容:
lst[1, 5, 6, 8, 9, 12] # slice a list by index
5个回答

17
使用 operator.itemgetter():
from operator import itemgetter

itemgetter(1, 5, 6, 8, 9, 12)(lst)

演示:

>>> from operator import itemgetter
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
>>> itemgetter(1, 5, 6, 8, 9, 12)(lst)
(2, 6, 7, 9, 10, 13)

这将返回一个元组;如果需要将其转换为列表,请使用 list(itemgetter(...)(lst))

请注意,这相当于一个带有索引集的切片表达式(lst[start:stop]),而不是范围;它不能用作左侧切片赋值(lst[start:stop] = some_iterable)。


你可以使用切片修改底层列表。你能用itemgetter做到吗? - David Heffernan
「咕噜咕噜」“一种做法” 「咕噜咕噜咕噜」😉 - user824425
我的意思是slice是Python中一个精确而具体的术语,正如你之前评论中提到的链接所定义的那样。而itemgetter不是Python中的splice,尽管它具有非常强的功能重叠。无论如何,你的更新很好! - David Heffernan
2
@DavidHeffernan:“slice”也可以指扩展切片(不受Python“list”类型支持),它允许使用[index1,index2,..,indexn]符号。 切片表达式的结果是一个新列表,我认为这就是OP想要的。 :-) 切片的另一种用法是作为赋值目标,我想这就是你的意思,但这在这里完全超出了范围。 我们只是在澄清术语! :-) - Martijn Pieters
仅供记录:在文档中,a[index1, index2, .., indexn]已经明确表示为订阅操作,而不是切片操作。 - Reinstate Monica
显示剩余6条评论

5
Numpy数组具有这种类型的切片语法:
In [45]: import numpy as np

In [46]: lst = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])

In [47]: lst[[1, 5, 6, 8, 9, 12]]
Out[47]: array([ 2,  6,  7,  9, 10, 13])

2
使用列表推导式很容易且直观地完成这个操作。
lst = range(1, 14)
indices = [1, 5, 6, 8, 9, 12]
filtered_lst = [lst[i] for i in indices]

1
我会选择Martijn Pieters建议的operator.itemgetter()方法,但为了完整起见,这里还有另一种方法。
In [23]: lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

In [24]: indices = set([1, 5, 6, 8, 9, 12])

In [25]: [n for i,n in enumerate(lst) if i in indices]
Out[25]: [2, 6, 7, 9, 10, 13]

0
Python的切片允许你将切片作为赋值的目标。而Python的切片语法不允许使用不规则索引的切片。因此,如果你想将你的“自定义”切片作为赋值的目标,那么使用Python切片语法是不可能的。
如果你的需求是通过复制指定元素来满足的,那么operator.itemgetter()可以满足你的需求。如果你需要切片赋值,那么numpy切片是一个很好的选择。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接