4

我对 Python 中的列表切片感到困惑。

对于列表

L=[0,1,2,3,4,5,6,7,8,9,10]

我想颠倒列表,可以得到答案

L[::-1] 

得到[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0].

但是,当我尝试

L[10:0:-1]

[10,9,8,7,6,5,4,3,2,1]没有0。既不L[10:1:-1]也不L[10:-1:-1]给出答案。

另一方面,L[200::-1],L[10:-12:-1] 给出正确答案,但L[200],L[-12]超出范围。

我想了解这种情况下 Python 的底层逻辑。谢谢你。

4

4 回答 4

5

我们以一个列表为例,

a = [1, 2, 3, 4, 4, 5, 6, 9]

如果您尝试使用正索引对其进行切片,

newa = a[1:5] 

这将导致

newa = [2, 3, 4, 4] 

这是因为,在上述情况下,切片是这样发生的,a[inclusive : exclusive],包含第一个索引,切片从该索引开始,仅在 index(5) 之前的一个索引结束,exclusive(remember)。这就是列表切片的工作方式。

要获取列表 a 的最后两个值,

newa = [6 : ]

这里,索引从 6(含)开始,一直到列表末尾。

如果您热衷于在列表中使用负索引,因为 Python 提供了简化索引的方法,请一劳永逸地了解切片的所有包容性和排他性。

对于上面的相同示例,要使用负索引获取列表的最后两个数字,我们所做的是,

newa = a[-2 : ]

在正索引的情况下,索引从 0 开始,而对于负索引,索引在 -1、-2 等处。所以在上面的例子中,从列表中倒数第二个数字开始,一直切到列表的末尾,这就是我们所理解的。

现在,要反转列表,可以这样做,

print a.reverse()
[9, 6, 5, 4, 4, 3, 2, 1]

在切片方式中,列表可以通过像上面提到的那样给它一个 [start, end, step] 来反转,但我想进一步澄清它。

 r = a[2: : -1]

这将创建一个从索引 2 开始的新列表,直到列表末尾,但由于步长为 -1,我们从索引 2 开始减少,直到达到 0。因此我们提出了一个反向列表 first三个数字如下:

r = [3, 2, 1]

此外,要使整个列表反转,

r = a[len(a): : -1]

这将从列表的长度 8 开始,但在从 0 开始的索引术语中,我们有 0 到 8 个索引,因此从第 8 个索引开始,它以 -1 的步长继续减少,直到列表的末尾. 结果如下:

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

我个人更喜欢用它来反转列表。

于 2014-07-14T19:03:03.673 回答
3

对于 Python 列表切片语法,list[start:end:step]将获得一个切片列表,其中包含以 开头的项目list[start],但list[end]被排除在外。因此,在您的情况下,L[10:0:-1]将排除L[0]0,并将L[10::-1]按您的预期工作。

startorend为负数时,表示从列表末尾开始计数。因此list[-1]将获得列表中的最后一项。在您的情况下,L[10:-1:-1]相当于L[10:10:-1]. 所以L[10:-1:-1]会得到[]

于 2013-09-13T08:15:25.723 回答
1
 >>> L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 >>> L[1:3]
 [1, 2]

指数3不包括

>>> L[0:10:1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

index10不包括在内,如果要全选,则应使用:

>>>L[0:11:1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

但是你不能得到L[11],它会被抛出IndexError,因为你只有 11 个元素,最大索引是 10,原因L[0:11:1]不会超出范围,因为这个切片不会L[11]只从索引 0 到 10 访问。

>>> L[10:0:-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

-1是逆向切片的一步,也是0排除,

并且L[10:-1:-1]等价于L[10:10:-1], 因为第一个-1表示 L 的最后一个索引

>>> L[10:-12:-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

index-11等价于 index 0, index-12等价于 index before0

于 2013-09-13T08:26:12.710 回答
1

上面的答案正确解释了使用列表切片时会发生什么。但是,我想谈谈问题的最后一部分——即使 200 和 12 都超出了数组的范围,它是如何工作的L[200::-1]L[10:-12:-1]

你可以这样简单地理解——当切片用于从序列中提取元素时,python 确保切片中使用的索引在序列的长度范围内。因此,在您的情况下,当您指定L[200::-1]时,内部发生的是 Python 检查序列的长度L是否仅为11,因此将上述语句视为L[10::-1]代替。类似的论点适用于L[10:-12:-1]

链接提供了对切片的深入了解。通常在本页的末尾有关于如何实现支持扩展切片的序列的描述和示例。去引用:

slice 对象现在有一个方法indices(length),给定一个序列的长度,返回一个可以直接传递给 range() 的 (start, stop, step) 元组。indices() 以与常规切片一致的方式处理省略和超出范围的索引(这个无害的短语隐藏了大量令人困惑的细节!)。

于 2013-09-13T08:46:49.120 回答