关于python:切片中的默认值是什么?

What are the default values set to in a slice?

我看了一下关于why-do-list-1-not-equal-listlenlist-1和python中的默认切片索引的顶级答案,了解切片中默认值的设置。两个最重要的答案都参考以下文档:

考虑到s[i:j:k]

If i or j are omitted or None, they become"end" values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1.

假设我有以下代码:

1
2
3
4
5
6
s ="hello"
forward_s = s[::1]
print(forward_s) # =>"hello"

backward_s = s[::-1]
print(backward_s) # =>"olleh"

我知道,如果省略了索引,那么python将其视为在这些地方使用了None的值。根据文件,[i:j:k]中的ij的指数根据k的符号设置为"结束"值。对于正的k,我假设i设置为0j设置为字符串长度。但是,为负的k设置的值是什么?

例如,以下内容也会反转字符串:

1
reversed_str = s[-1:-6:-1]

那么,当k = -1时,i的默认值可能设置为-1j的默认值设置为-len(s) - 1


默认值为NoneNoneNone

1
2
3
4
5
6
class Sliceable(object):
    def __getitem__(self, slice):
        print(slice)

Sliceable()[::]
>>> slice(None, None, None)

这与事实无关,即slice()确实需要stop论证。库文档对此不太明确,但C API明确指出,所有三个值都可能是空的:

The start, stop, and step parameters are used as the values of the slice object attributes of the same names. Any of the values may be NULL, in which case the None will be used for the corresponding attribute.

由可切片的对象来理解默认值。约定是使用第一个元素、最后一个元素、内部集合实现的最小步进:

1
2
3
4
5
l = [1, 2, 3]
l[slice(None, None, None])
>>> [1, 2, 3]
s[None:None:None])
>>> [1, 2, 3]

负步进将导致默认的startend值在语义上颠倒,即:

1
2
3
4
5
s = 'abc'
s[slice(None, None, -1)]
>>> 'cba'
s[::-1]
>>> 'cba'

注意,这并不意味着一个简单的值翻转,end的默认值通常是"在任何方向上超过序列末尾的一个",因为range()不包含结束值,但切片的默认值应包括完整序列。

记录如下:

s[i:j:k]

The slice of s from i to j with step k is defined as the sequence of items with index x = i + n*k such that 0 <= n < (j-i)/k. In other words, the indices are i, i+k, i+2*k, i+3*k and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. When k is negative, i and j are reduced to len(s) - 1 if they are greater. If i or j are omitted or None, they become"end" values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1.