Python中list的切片細節

橫雲斷嶺發表於2011-06-12

Python中的切片功能強大。但是切片很容易讓人搞混。

個人覺得Python的文件不怎麼好,好多東西都是零散的,更像教科書。

下面的參考來自Python3.2文件和Python參考手冊(第4版):

a = [1,2,3,4]
x = a[1:2] #a.__getitem__(slice(1,2,None))
slice([start], stop[, step])
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.
range([start], stop[, step])
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).
 

 

可以看到,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]
a[:5:-1] #step < 0,所以start = 9
a[0:5:-1] #指定了start = 0
a[1::-1] #step < 0,所以stop = 0 

Python3程式碼:

l = list(range(10))
print(l[5:0:-1])
print(l[5:4:-1])
print(l[:3:-1])
print(l[0:3:-1])
print(l[9::-1])

輸出:

 

[5, 4, 3, 2, 1]
[5]
[9, 8, 7, 6, 5, 4]
[]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 


相關文章