范围(n)[x:y:z]

range(n)[x:y:z]

不确定 [ ] 中的参数在 range() 函数之后的实际作用。

指数:print ( range(5)[::-2]) 输出:[4, 2, 0]

但是如果[x:y:z]代表[start:stop:step],那么当我输入print(range(5)[4:-2:-2])时,输出列表是[4]而不是[4, 2, 0],不知道如何行得通。

你可以把 [x:y:z] 代表 [start:stop:jumps] 在 5 的范围内,它会迭代 0-4,包括两者,因为你的 z 是负的,它会从 4 迭代到0 with 2 jumps 4---3---2(---代表跳跃)所以输出是 4---(3)---2---(1)---0 。 ------> -------->

快乐编码

你没看错,是[start:stop:step]。请注意,负开始和停止被定义为在序列末尾开始。因此,对于以值 2, 3, 4 结尾的范围,停止点 -2 指的是 3(-1 是最后一个,-2 是倒数第二个,依此类推)。

所以在您的例子中,范围的长度为 5,从 0 开始到 4 结束。您从索引 4 开始,到索引 -2 结束,即 5-2 = 3。到目前为止,索引指的是 [3, 4]。现在,从 4 开始,负步为 2。因此您跳过了 3,结果只有 [4].

如果你想要[4, 2, 0],那么你应该省略止损:

>>> range(5)[4::-2]
[4, 2, 0]

实际上你甚至可以省略开头:

>>> range(5)[::-2]
[4, 2, 0]

but range(5)[4:-2] results []. Then how range(5)[4:-2:-2] results [4]?

切片被立即计算,而不是一个接一个地计算:

计算负止损后,range(5)[4:-2]等价于range(5)[4:3]。由于没有指定步长,因此将使用默认步长 1。这意味着切片必须从索引 4 到索引 3,并且步长为正。那是不可能的,所以返回一个空列表。

当我们有负步时,它看起来像这样:range(5)[4:3:-2]。现在,由于我们有一个负步骤,所以方向是相反的。所以我们可以从索引 4 开始,然后转到较低的索引 3。

只是定义了对于正步,stop >= start 需要为真,而对于负步,则为逆,stop <= start.

在Python3中,range()创建了一个特殊的range对象。在 Python 2 中,它创建了一个 list.

List element:     0  1  2  3  4
Index:            0  1  2  3  4
Backwards index: -5 -4 -3 -2 -1

因此,从索引 4 到索引 -2 实际上是从列表元素 4 到列表元素 3。由于您跳过了所有其他元素,因此您不会到达 3,只剩下 [4].

根据 [start:stop:step] 定义的具有三个参数的切片。巧合的是,这也是使用三个参数定义范围对象的方式。我们很快就会看到它是如何发挥作用的。

你在做什么是这样的:

>>> range(5)
[0, 1, 2, 3, 4]
>>> range(5)[4:-2:-2]
[4]

Python 中的负索引从序列的长度环绕。所以你的列表的长度是 5,然后你用 -2 向下两步,所以你得到索引 3 作为你的停止值。换句话说,索引 3 是迭代器的标记值,切片操作将在该点停止收集元素。您将每一步降低 2 个索引,但索引 3 是哨兵,因此切片在获取索引 4 处的元素并到达停止索引后停止收集元素。

您可能真正想做的是:

>>> range(4, -2, -2)
[4, 2, 0]