Python 切片和负步幅 - 为什么这些例子显然是矛盾的?

stk*_*ent 4 python slice

我在这里阅读了很多关于将切片与负步幅相结合的答案,但以下问题仍然让我感到困惑。在几个地方,我已经看到下图用于说明切片符号的工作原理(指的是间隙,而不是条目):

 +---+---+---+---+
 | T | e | s | t |
 +---+---+---+---+
 0   1   2   3   4
-4  -3  -2  -1  
Run Code Online (Sandbox Code Playgroud)

这些例子与上图一致:

>>> "Test"[2:]
'st'

>>> "Test"[-2:]
'st'
Run Code Online (Sandbox Code Playgroud)

>>> "Test"[-2::-1]
'seT'
Run Code Online (Sandbox Code Playgroud)

似乎不一致 - 如果从-2分隔符开始,然后向后计数,为什么s还包含在返回的字符串中?

Mar*_*ers 5

因此,您拥有的心智模型仅对正步幅值有用,但在使用负步幅时无济于事。请改用以下图片:

  +---+---+---+---+
  | T | e | s | t |
  +---+---+---+---+
    0   1   2   3   4
-5 -4  -3  -2  -1  
Run Code Online (Sandbox Code Playgroud)

在哪里标记索引,而不是边界。

边界模型很好,但只是为了更容易忘记最终索引不包含在结果值中的事实。通过仅对索引进行编号并省略结束索引,您可以看到正步和负步是如何工作的。

有关详细信息,请查看 Python 计算切片方式的官方文档;来自序列类型注释(注释 5):

s[i:j:k]
sfrom ito jwith step 的切片k被定义为具有索引的项目序列,x = i + n*k使得0 <= n < (j-i)/k. 换句话说,在指数ii+ki+2*ki+3*k等等,停止时j达到的(但绝不包括j)。如果ij大于len(s),则使用len(s)。如果ij省略 or None,它们将成为“结束”值(结束取决于 的符号k)。注意,k不能为零。如果kNone,则将其视为1.

因此,对于您的负步幅,值变为:

i = len(s) - 2 = 2 
j = None = -1 (end for negative strides, *not* len(s) - 1)
k = -1
Run Code Online (Sandbox Code Playgroud)

j“结束”在哪里,这里是-1,因为这是您在负步骤中用完字符串的点。然后索引变为:

x0 = i + 0*k = 2
x1 = i + 1*k = 1
x2 = i + 2*k = 0
Run Code Online (Sandbox Code Playgroud)

给你 3 个索引。