Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。
另请参见:为什么切片和范围上限是互斥的?
Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。
另请参见:为什么切片和范围上限是互斥的?
当前回答
我个人认为这就像一个for循环:
a[start:end:step]
# for(i = start; i < end; i += step)
此外,请注意,start和end的负值是相对于列表末尾的,并且在上面的示例中通过given_index+a.shape[0]计算。
其他回答
枚举序列x语法允许的可能性:
>>> x[:] # [x[0], x[1], ..., x[-1] ]
>>> x[low:] # [x[low], x[low+1], ..., x[-1] ]
>>> x[:high] # [x[0], x[1], ..., x[high-1]]
>>> x[low:high] # [x[low], x[low+1], ..., x[high-1]]
>>> x[::stride] # [x[0], x[stride], ..., x[-1] ]
>>> x[low::stride] # [x[low], x[low+stride], ..., x[-1] ]
>>> x[:high:stride] # [x[0], x[stride], ..., x[high-1]]
>>> x[low:high:stride] # [x[low], x[low+stride], ..., x[high-1]]
当然,如果(高低)%步幅!=0,则终点将略低于高1。
如果步幅为负,则由于我们正在倒计时,顺序会有点改变:
>>> x[::-stride] # [x[-1], x[-1-stride], ..., x[0] ]
>>> x[high::-stride] # [x[high], x[high-stride], ..., x[0] ]
>>> x[:low:-stride] # [x[-1], x[-1-stride], ..., x[low+1]]
>>> x[high:low:-stride] # [x[high], x[high-stride], ..., x[low+1]]
扩展切片(带逗号和省略号)通常仅用于特殊数据结构(如NumPy);基本序列不支持它们。
>>> class slicee:
... def __getitem__(self, item):
... return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
Python教程对此进行了讨论(向下滚动一点,直到您了解到关于切片的部分)。
ASCII艺术图也有助于记住切片的工作方式:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
记住切片工作方式的一种方法是将索引视为字符之间的指针,第一个字符的左边缘编号为0。然后,n个字符串的最后一个字符的右边缘具有索引n。
已经有很多答案了,但我想添加一个性能比较
~$ python3.8 -m timeit -s 'fun = "this is fun;slicer = slice(0, 3)"' "fun_slice = fun[slicer]"
10000000 loops, best of 5: 29.8 nsec per loop
~$ python3.8 -m timeit -s 'fun = "this is fun"' "fun_slice = fun[0:3]"
10000000 loops, best of 5: 37.9 nsec per loop
~$ python3.8 -m timeit -s 'fun = "this is fun"' "fun_slice = fun[slice(0, 3)]"
5000000 loops, best of 5: 68.7 nsec per loop
~$ python3.8 -m timeit -s 'fun = "this is fun"' "slicer = slice(0, 3)"
5000000 loops, best of 5: 42.8 nsec per loop
因此,如果您重复使用同一个切片,使用切片对象将有益并提高可读性。然而,如果您只进行了几次切片,则应首选[:]表示法。
这里有一个简单的记忆方法,可以记住它是如何工作的:
S L*I*C*E*切片的“i”位于第一位,代表包容,“e”排在最后,代表独占。
所以array[j:k]将包括第j个元素,并排除第k个元素。
使用一点后,我意识到最简单的描述是它与for循环中的参数完全相同。。。
(from:to:step)
其中任何一项都是可选的:
(:to:step)
(from::step)
(from:to)
然后,负索引只需要将字符串的长度添加到负索引中即可理解它。
不管怎样,这对我来说都很有效。。。