协慌网

登录 贡献 社区

理解 Python 的切片表示法

我需要在 Python 的切片表示法上有一个很好的解释(引用是一个加号)。

对我而言,这种符号需要一点点提升。

它看起来非常强大,但我还没有完全理解它。

答案

它非常简单:

a[start:end] # items start through end-1
a[start:]    # items start through the rest of the array
a[:end]      # items from the beginning through end-1
a[:]         # a copy of the whole array

还有step值,可以与上述任何一个一起使用:

a[start:end:step] # start through not past end, by step

要记住的关键点是:end值表示不在所选切片中的第一个值。因此, endstart的差异是所选元素的数量(如果step为 1,则为默认值)。

另一个特性是startend可能是负数 ,这意味着它从数组的末尾而不是从开头开始计数。所以:

a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items

同样, step可能是负数:

a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed

如果项目少于您的要求,Python 对程序员很友好。例如,如果你问a[:-2]a只包含一个元素,你会得到一个空的列表,而不是一个错误。有时您会更喜欢错误,因此您必须意识到这可能会发生。

Python 教程讨论它(向下滚动一下,直到你得到关于切片的部分)。

ASCII 艺术图也有助于记住切片的工作方式:

+---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

记住切片如何工作的一种方法是将索引视为指向字符之间 ,第一个字符的左边缘编号为 0. 然后, n个字符串的最后一个字符的右边缘具有索引n

列举语法允许的可能性:

>>> seq[:]                # [seq[0],   seq[1],          ..., seq[-1]    ]
>>> seq[low:]             # [seq[low], seq[low+1],      ..., seq[-1]    ]
>>> seq[:high]            # [seq[0],   seq[1],          ..., seq[high-1]]
>>> seq[low:high]         # [seq[low], seq[low+1],      ..., seq[high-1]]
>>> seq[::stride]         # [seq[0],   seq[stride],     ..., seq[-1]    ]
>>> seq[low::stride]      # [seq[low], seq[low+stride], ..., seq[-1]    ]
>>> seq[:high:stride]     # [seq[0],   seq[stride],     ..., seq[high-1]]
>>> seq[low:high:stride]  # [seq[low], seq[low+stride], ..., seq[high-1]]

当然,如果(high-low)%stride != 0 ,则终点将略低于high-1

如果stride为负,则排序会因为我们倒计时而改变一点:

>>> seq[::-stride]        # [seq[-1],   seq[-1-stride],   ..., seq[0]    ]
>>> seq[high::-stride]    # [seq[high], seq[high-stride], ..., seq[0]    ]
>>> seq[:low:-stride]     # [seq[-1],   seq[-1-stride],   ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]

扩展切片(带逗号和省略号)主要仅由特殊数据结构(如 Numpy)使用; 基本序列不支持它们。

>>> class slicee:
...     def __getitem__(self, item):
...         return `item`
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'