Python中的切片功能強大。但是切片很容易讓人搞混。
個人覺得Python的文檔不怎麼好,好多東西都是零散的,更像教科書。
下面的參考來自Python3.2文檔和Python參考手冊(第4版):
a = [1,2,3,4]<br />x = a[1:2] #a.__getitem__(slice(1,2,None))<br />slice([start], stop[, step])<br />Return a slice object representing the set of indices specified by range(start, stop, step). The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default). They have no other explicit functionality; however they are used by Numerical Python and other third party extensions. Slice objects are also generated when extended indexing syntax is used. For example: a[start:stop:step] or a[start:stop, i]. See itertools.islice() for an alternate version that returns an iterator.<br />range([start], stop[, step])<br />This is a versatile function to create iterables yielding arithmetic progressions. It is most often used in for loops. The arguments must be integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns an iterable of integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised).<br />
可以看到,list的切片,內部是調用__getitem__,和slice函數。而slice函數又是和range()函數相關的。
range([start], stop[, step])
[start, start + step, start + 2 * step, ...]
真正讓人迷惑的是list[start:stop:step]中的start和stop的預設值。
按《Python參考手冊(第4版)》的說法:
如果不指定start和stop具體值
當step>0時,start和stop預設值是索引的開頭
當step<0時,start和stop預設值是索引的結尾
我仔細再想下,發現有點不妥,a[::-1]又怎樣解釋?
我覺得step的符號表示一種方向的含義:
+:即從左向右看,所以start預設是0,stop預設是索引最大值
- :即從右向左看,所以start預設是索引最大值,stop預設是0
如:
a = [0,1,2,3,4,5,6,7,8,9]<br />a[:5:-1] #step < 0,所以start = 9<br />a[0:5:-1] #指定了start = 0<br />a[1::-1] #step < 0,所以stop = 0
Python3代碼:
l = list(range(10))<br />print(l[5:0:-1])<br />print(l[5:4:-1])<br />print(l[:3:-1])<br />print(l[0:3:-1])<br />print(l[9::-1])
輸出:
[5, 4, 3, 2, 1]<br />[5]<br />[9, 8, 7, 6, 5, 4]<br />[]<br />[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]