1. 程式人生 > 其它 >Python:【基礎語法】 切片

Python:【基礎語法】 切片

切片

一、索引

包括:正索引和負索引兩部分,如下圖所示,以list物件a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]為例:

二、切片基本內容

一個完整的切片表示式包含兩個“:”,用於分隔三個引數(start_index、end_index、step)。
當只有一個“:”時,預設第三個引數step=1;當一個“:”也沒有時,start_index=end_index,表示切取start_index指定的那個元素。

#切片基本表示式:
object[start_index:end_index:step]

step:正負數均可,其絕對值大小決定了切取資料時的“步長”,而正負號決定了“切取方向”,正表示“從左往右”取值,負表示“從右往左”取值。當step省略時,預設為1,即從左往右以步長1取值。
【當step為負數時,start_index必須在end_index的右邊。當step為正數時,start_index必須在end_index的左邊。】

start_index:表示起始索引(包含該索引對應值);該引數省略時,表示從物件“端點”開始取值,至於是從“起點”還是從“終點”開始,則由step引數的正負決定,step為正從“起點”開始,為負從“終點”開始。

end_index:表示終止索引(不包含該索引對應值);該引數省略時,表示一直取到資料“端點”,至於是到“起點”還是到“終點”,同樣由step引數的正負決定,step為正時直到“終點”,為負時直到“起點”。

三、切片例項

以下示例均以list物件a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]為例:

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

1.切取單個元素

#當索引只有一個數時,表示切取某一個元素。
>>>a[0]
0
>>>a[-4]
6

2.切取完整物件

#從左往右
#只有一個":",step預設為1。start_index預設為起點(左端點)。end_index預設為終點(右端點)。
>>>a[:] 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#從左往右
#兩個":",step預設為1。start_index預設為起點(左端點)。end_index預設為終點(右端點)。
>>>a[::]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#從右往左
#兩個":",step確定為-1,則方向是“從右向左”,因此start_index預設為終點(右端點)。end_index預設為起點(左端點)。
>>>a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

3.start_index與end_index全為正索引

(1)當兩個索引都為具體數值時(不是預設值,即沒有省略),具體擷取元素位置的兩種記憶方法:
首先,先根據確定索引判定取值方向是否存在矛盾,若矛盾則為空值;否則按下面方式取值
①從start_index開始,共end_index-start_index個元素;②從下標start_index開始,到下標end_index-1結束

(2)當索引存在省略,即要使用其預設值時,則只用辨別清從哪個元素(位置)開始,到哪個元素(位置)結束即可。
①無論誰省略,先根據step方向,確定省略索引其為起點還是終點。
②再從start_index位置的數(包含start_index)取到end_index位置
③若end_index為確定值(非省略),則取到end_index前(根據方向確定)的數(不包含end_index);
若end_index為省略值,則最終就取到end_index位置的數(包含end_index

#step=1,從左往右取值,start_index=1到end_index=6同樣表示從左往右取值。
>>>a[1:6]
[1, 2, 3, 4, 5]
#輸出為空列表,說明沒取到資料。
#step=-1,決定了從右往左取值(起點必須在終點右邊),而start_index=1到end_index=6決定了從左往右取值,兩者矛盾,所以為空
>>>a[1:6:-1]
[]
#輸出為空列表
#step=1,決定了從左往右取值(起點必須在終點左邊),而start_index=6到end_index=2決定了從右往左取值,兩者矛盾,所以為空。
>>>a[6:2]
[]
#step=1,表示從左往右取值,start_index的預設值根據step的方向確定,因為是從左往右,右邊end_index=6,則左邊start_index預設值為左端點(起點,0)
#從start_index=0開始取值,到end_index=6前一個數,即end_index=5
>>>a[:6]
[0, 1, 2, 3, 4, 5]
#step=-1,表示從右往左取值,start_index的預設值根據step的方向確定,因為是從右往左,左邊end_index=6,則右邊start_index預設值為右端點(終點,9)
#從start_index=9開始取值,到end_index=6前一個數,即end_index=7(因為方向是從右往左,因此前一個下標為7)
>>>a[:6:-1]
[9,8,7]
#step=1,從左往右取值,end_index的預設值根據step的方向確定,因為是從左往右,左邊start_index=6,則右邊end_index預設值為右端點(終點,9)
#end_index為省略值,經過確定其為終點,則從start_index=6取值,取到end_index=9
>>>a[6:]
[6, 7, 8, 9]
#step=-1,從右往左取值,end_index的預設值根據step的方向確定,因為是從右往左,右邊start_index=6,則左邊end_index預設值為左端點(起點,0)
#end_index為省略值,經過確定其為起點,則從start_index=6取值,取到end_index=0
>>>a[6::-1]
[6, 5, 4, 3, 2, 1, 0]

4.start_index與end_index全為負索引

(1)與正索引相同,當兩個索引為確定值時,具體擷取元素位置:
首先,先根據確定索引判定取值方向是否存在矛盾,若矛盾則為空值;否則按下面方式取值
①從start_index開始,共擷取|end_index-start_index|個元素;②從start_index開始,到end_index的後一個元素結束

(2)當索引存在省略,即要使用其預設值時,則只用辨別清從哪個元素(位置)開始,到哪個元素(位置)結束即可。
①無論誰省略,先根據step方向,確定省略索引其為起點還是終點。
②再從start_index位置的數(包含start_index)取到end_index位置
③若end_index為確定值(非省略),則取到end_index前(根據方向確定)的數(不包含end_index);
若end_index為省略值,則最終就取到end_index位置的數(包含end_index

#step=1,從左往右取值,而start_index=-1到end_index=-6決定了從右往左取值,兩者矛盾,所以為空。
>>>a[-1:-6]
[]
#step=-1,從右向左取值,而start_index=-1到end_index=-6同樣是從右向左
#負索引的
>>>a[-1:-6:-1]
[9, 8, 7, 6, 5]
#step=1,從左往右取值,而start_index=-6到end_index=-1同樣是從左往右取值。
>>>a[-6:-1]
[4, 5, 6, 7, 8]
#step=1,從左往右取值,start_index的預設值根據step的方向確定,因為是從左往右,右邊end_index=-6,則左邊預設值為左端點(起點,-10)
>>>a[:-6]
[0, 1, 2, 3]
#step=-1,從右往左取值,start_index的預設值根據step的方向確定,因為是從右往左,左邊end_index=-6,則右邊預設值為右端點(終點,-1)
>>>a[:-6:-1]
[9, 8, 7, 6, 5]
#step=1,從左往右取值,end_index的預設值根據step的方向確定,因為是從左往右,左邊end_index=-6,則右邊預設值為右端點(終點,-1)
>>>a[-6:]
[4, 5, 6, 7, 8, 9]
#step=-1,從右往左取值,end_index的預設值根據step的方向確定,因為是從右往左,右邊end_index=-6,則左邊預設值為左端點(起點,-10)
>>>a[-6::-1]
[4, 3, 2, 1, 0]

5.start_index與end_index正負索引混合

此類不存在索引有省略值的情況,因此只要判定清起始位置和結束位置即可。
end_index確定,則取到其前(根據方向確定)一個數。

#step=1,從左往右取值,start_index=1在end_index=-6的左邊,不存在矛盾
#從start_index=1的數取到end_index=-6前一個數,即end_index=-7(end_index=3)
>>>a[1:-6]
[1, 2, 3]
#step=-1,從右往左取值,start_index=1在end_index=-6的左邊,存在矛盾,因此為空
>>>a[1:-6:-1]
[]
#step=1,從左往右取值,start_index=-1在end_index=6的右邊,存在矛盾,因此為空
>>>a[-1:6]
[]
#step=-1,從右往左取值,start_index=-1在end_index=6的右邊,不存在矛盾
#從start_index=-1(start_index=9)的數取到end_index=6前一個數,即end_index=7
>>>a[-1:6:-1]
[9, 8, 7]

6.其他物件的切片

前面的切片操作以list物件為例進行說明,但實際上可進行切片操作的資料型別還有很多,包括元組、字串等等。

#字串的切片操作
>>>'ABCDEFG'[::2]
'ACEG'
#利用range()函式生成1-99的整數,然後從start_index=2(即3)開始以step=3取值,直到終點,再在新序列中取最後五個數。
>>>for i in range(1,100)[2::3][-5:]: 
       print(i)
87
90
93
96
99

7.常用操作

①取偶數位置

>>>b = a[::2]
[0, 2, 4, 6, 8]

②取奇數位置

>>>b = a[1::2]
[1, 3, 5, 7, 9]

③拷貝物件

#方法1 [:]
>>>b = a[:] #
>>>print(b) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>print(id(a)) #41946376
>>>print(id(b)) #41921864

#方法2 copy()
>>>b = a.copy()
>>>print(b) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>print(id(a)) #39783752
>>>print(id(b)) #39759176

需要注意的是:[:]和.copy()都屬於“淺拷貝”,只拷貝最外層元素,內層巢狀元素則通過引用方式共享,而非獨立分配記憶體

④修改單個元素

>>>a[3] = ['A','B']
[0, 1, 2, ['A', 'B'], 4, 5, 6, 7, 8, 9]

⑤在某個位置插入元素

>>>a[3:3] = ['A','B','C']
[0, 1, 2, 'A', 'B', 'C', 3, 4, 5, 6, 7, 8, 9]
>>>a[0:0] = ['A','B']
['A', 'B', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

⑥替換部分元素

>>>a[3:6] = ['A','B']
[0, 1, 2, 'A', 'B', 6, 7, 8, 9]

四、總結

(一)start_index、end_index、step三者可同為正、同為負,或正負混合。但必須遵循一個原則,即:當start_index表示的實際位置在end_index的左邊時,從左往右取值,此時step必須是正數(同樣表示從左往右);當start_index表示的實際位置在end_index的右邊時,表示從右往左取值,此時step必須是負數(同樣表示從右往左),即兩者的取值順序必須相同。

(二)當start_index或end_index省略時,取值的起始索引和終止索引由step的正負來決定,這種情況不會有取值方向矛盾(即不會返回空列表[]),但正和負取到的結果順序是相反的,因為一個向左一個向右。

(三)step的正負是必須要考慮的,尤其是當step省略時。比如a[-1:],很容易就誤認為是從“終點”開始一直取到“起點”,即a[-1:]= [9, 8, 7, 6, 5, 4, 3, 2, 1, 0],但實際上a[-1:]=[9](注意不是9),原因在於step省略時step=1表示從左往右取值,而起始索引start_index=-1本身就是物件的最右邊元素了,再往右已經沒資料了,因此結果只含有9一個元素。

(四)需要注意:“取單個元素(不帶“:”)”時,返回的是物件的某個元素,其型別由元素本身的型別決定,而與母物件無關,如上面的a[0]=0、a[-4]=6,元素0和6都是“數值型”,而母物件a卻是“list”型;“取連續切片(帶“:”)”時,返回結果的型別與母物件相同,哪怕切取的連續切片只包含一個元素,如上面的a[-1:]=[9],返回的是一個只包含元素“9”的list,而非數值型“9”。

https://www.jianshu.com/p/15715d6f4dad