Python列表错误:[: - 1]踩到[:-1]切片

Mat*_*lty 17 python reverse slice

我以为我理解了python中列表切片的基础知识,但是在切片上使用负步骤时收到了意外错误,如下所示:

>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[:-1]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> a[:-1:-1]
[]
Run Code Online (Sandbox Code Playgroud)

(请注意,这是在Python 3.5中运行)

为什么[: - 1:-1]不会以与使用[:: - 1]的整个列表相同的方式反向遍历a [: - 1]切片?

我意识到你也可以使用list.reverse(),但试图更好地理解底层的python切片功能.

NPE*_*NPE 22

第一个-1a[:-1:-1]不意味着什么,你认为它.

在切片中,负起始/结束索引不是按字面解释的.相反,它们用于方便地引用列表的末尾(即它们是相对的len(a)).无论切片的方向如何,都会发生这种情况.

这意味着

a[:-1:-1]
Run Code Online (Sandbox Code Playgroud)

相当于

a[:len(a)-1:-1]
Run Code Online (Sandbox Code Playgroud)

在反向切片期间省略时,起始索引默认为len(a)-1,使上述等价于

a[len(a)-1:len(a)-1:-1]
Run Code Online (Sandbox Code Playgroud)

这总是给出一个空列表,因为开始和结束索引是相同的,而结束索引是独占的.

要反向切换到第0个元素并包含第0个元素,您可以使用以下任何符号:

>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> a[:None:-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> a[:-len(a)-1:-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Run Code Online (Sandbox Code Playgroud)


god*_*ygo 8

当你输入[1, 2, 3, ...][1:4:1]它时,它是相同的[1, 2, 3, ...][slice(1, 4, 1)].对象1:4:1的简写也是如此slice.slice签名是slice(stop)或者slice(start, stop[, step])你也可以None用于参数.

:: -> slice(None, None, None)
:4 -> slice(4)
# and so on
Run Code Online (Sandbox Code Playgroud)

假设我们有[a: b: c].指数规则如下:

  1. 首先c检查.默认为+1,c表示步骤的前进或后退方向的符号.绝对值c表示步长.
  2. a检查.当c为正或None默认为a0.如果c是负的,默认a-1.
  3. 最后b检查.当c为正或None默认为blen.如果c是负的默认值b-(len+1).

注1:Python中的退化切片处理得很好:

  • len或替换太大或太小的索引0.
  • 小于下限的上限返回空列表或字符串或其他任何内容(对于正数c).

注2:粗略地说,Python的,而这种情况拾取元件(a < b) if (c > 0) else (a > b)True(更新a += c在每一个步骤).此外,所有负面指数都被替换为len - index.

如果您将这些规则和注释结合起来,那么为什么您有一个空列表就有意义了.在你的情况下:

 In[1]: [1, 2, 3, 4, 5, 6][:-1:-1]        # `c` is negative so `a` is -1 and `b` is -1
Out[1]: [] 

# it is the same as:

 In[2]: [1, 2, 3, 4, 5, 6][-1: -1: -1]    # which will produce you an empty list 
Out[2]: [] 
Run Code Online (Sandbox Code Playgroud)

关于切片表示法有很好的讨论:解释Python的切片表示法!