Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。
另请参见:为什么切片和范围上限是互斥的?
Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。
另请参见:为什么切片和范围上限是互斥的?
当前回答
已经有很多答案了,但我想添加一个性能比较
~$ 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
因此,如果您重复使用同一个切片,使用切片对象将有益并提高可读性。然而,如果您只进行了几次切片,则应首选[:]表示法。
其他回答
Python教程对此进行了讨论(向下滚动一点,直到您了解到关于切片的部分)。
ASCII艺术图也有助于记住切片的工作方式:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
记住切片工作方式的一种方法是将索引视为字符之间的指针,第一个字符的左边缘编号为0。然后,n个字符串的最后一个字符的右边缘具有索引n。
在找到这张很棒的桌子http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Python indexes and slices for a six-element list.
Indexes enumerate the elements, slices enumerate the spaces between the elements.
Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5]
Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4]
+---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3]
| a | b | c | d | e | f | a[5]==5 a[1:2]==[1]
+---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4]
Slice from front: : 1 2 3 4 5 : a[-2]==4
Slice from rear: : -5 -4 -3 -2 -1 :
b=a[:]
b==[0,1,2,3,4,5] (shallow copy of a)
当我第一次看到切片语法时,有一些事情不是很明显:
>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]
反转顺序的简单方法!
如果出于某种原因,您希望以相反的顺序进行每一项:
>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]
如果我们可以将切片与范围联系起来,这很容易理解,因为范围给出了索引。我们可以将切片分为以下两类:
1.无台阶或台阶>0。例如,[i:j]或[i:j:k](k>0)
假设序列为s=[1,2,3,4,5]。
如果0<i<len(s)和0<j<len,则[i:j:k]->范围(i,j,k)
例如,[0:3:2]->范围(0,3,2)->0,2
如果i>len或j>len,则i=len或j=len
例如,[0:100:2]->范围(0,len(s),2)->范围(0,5,2)->0,2,4
如果i<0或j<0,则i=max(0,len(s)+i)或j=max
例如,[0:-3:2]->范围(0,len(s)-3,2)->范围(0,2,2)->0
例如,[0:-1:2]->范围(0,len(s)-1,2)->范围(0,4,2)->0,2
如果未指定i,则i=0
例如,[:4:2]->范围(0,4,2)->范围(4,2)->0,2
如果未指定j,则j=len(s)
例如,[0::2]->范围(0,len(s),2)->范围(0,5,2)->0,2,4
2.步骤<0。例如,[i:j:k](k<0)
假设序列为s=[1,2,3,4,5]。
如果0<i<len(s)和0<j<len,则[i:j:k]->范围(i,j,k)
例如,[5:0:-2]->范围(5,0,-2)->5,3,1
如果i>len或j>len,则i=len(s)-1或j=len(s)-1
例如,[100:0:-2]->范围(len(s)-1,0,-2)->范围(4,0,-2)->4,2
如果i<0或j<0,则i=max(-1,len(s)+i)或j=max(-1len(s)+j)
例如,[-2:-10:-2]->range(len(s)-2,-1,-2)->range(3,-1,-1)->3,1
如果未指定i,则i=len(s)-1
例如,[:0:-2]->范围(len(s)-1,0,-2)->范围(4,0,-2)->4,2
如果未指定j,则j=-1
例如,[2::-2]->范围(2,-1,-2)->2,0
例如,[::-1]->range(len(s)-1,-1,-1)->range(4,-1,1)->4,3,2,1,0
总而言之
这只是为了一些额外的信息。。。考虑以下列表
>>> l=[12,23,345,456,67,7,945,467]
反转列表的其他几个技巧:
>>> l[len(l):-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[len(l)::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[-1:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]