1. 什麼是 Python 字符串切片?
例如存在字符串 str2 = “abcd1234"
,有以下簡單的切片應用。
str2[0] # a
str2[0:3] # abc
str2[0:6:2] # ac1
有 3 種形式的切片:
- string[index]: 獲取字符串特定下標字符
- string[start, stop]: 獲取從 start 座標到 stop 座標的字符串,注意左閉右開,既 [start, stop) 範圍座標的字符串
- string[start, stop, step]: 獲取從 start 座標到 stop 座標的字符串,且一次提取間隔爲 step
上面都是一些基礎的應用,在此之上,還有高級的特性:
- 座標爲空則默認(提取方向的)開頭或者結尾,步級(step)爲空則默認爲1
- 不管是座標還是步級(step),都支持正負數
例如有以下高級應用:
str2[1::2] # bd24
str2[:-1:1] # abcd123
特性1 比較好理解,但特性2 的存在讓字符串切片存在更多的玩法,但也讓切片更難理解。
小領悟就是關於怎麼理解這高級的切片功能,讓我們看着代碼就可以知道其切片結果。
2. 切片的理解
2.1 切片的基礎概念
以最複雜最完整的第三種切片方法 string[start, stop, step]
爲例,start,stop 劃定了切片的範圍,如下圖:
step 確定了在範圍內 挑選 的跨度,以 step = 2 爲例,如下圖:
2.1 座標正負的含義
如上圖所示,
- 以正數表示座標,則座標是從左到右,從 0 開始計數
- 以負數表示座標,則座標是從右到左,從 -1 開始計數
- 0 不分正負,不管正座標還是負座標,都規定 0 恆指向左邊第一個元素
因此字符串中每一個元素都至少有2個座標可以表示。以字符 d
爲例,其座標既可以是 3,也可以是 -5,因此 str2[3]
和 str2[-5]
指向同一個字符,他們是等效的。
print(str2[3] is str2[-5]) # True
這個等效的概念很重要,正因爲這個概念,start、stop 可以是正負任意的組合,例如:
str2[2:5] # cd1
str2[-6:-3] # cd1
str2[-6:5] # cd1
str2[2:-3] # cd1
上面的 4 中寫法是完全等效的,不管 start 是 2 還是 -6 都指向 ‘c’,不管 stop 是 5 還是 -3 都指向 ‘2’。
2.2 步級正負的含義
在一定的條件下,我們可以理解爲 start + step 就是下一個切片的元素座標。
以 str2[1:6:2]
爲例,如下圖:
爲什麼是一定條件下才成立呢?例如切片:str2[-7:6:2]
,如果按 start + step 的計算,[-7, 6) 之間的座標數據全亂了。
- 正確座標:1,3,5
- 錯誤座標:-7, -5, -3, -1, 1, 3,5
所以,如果按 start + step 的計算前提,應該是 start 和 stop 座標 同爲正數或者負數,同樣以 str2[-7:6:2]
爲例,座標 -7 元素對應的正座標是 1,等效於 str2[1:6:2]
,或者 str2[-7:-2:2]
,此時通過 start + step 的計算可以獲取正確的切片提取座標。
總的來說:正的步級表示從左往右,負的步級表示從右往左,從 start 到 stop 按步級正負指定的方向提取。
2.3 特殊切片結果的理解
基於上面的理解,同樣以 str2 = "abcd1234"
爲例,我們試着分析以下的切片。
2.3.1 str2[::-1]
- 步級爲負數,表示提取方向從右到左
- 步級爲1,表示每跨步1個元素提取
- start 爲空,則默認爲字符串提取方向的最開始
- end 爲空,則默認爲字符串提取方向的最後
因此最終結果如下,起到個倒序的效果:
print(str2[::-1]) # 4321dcba
2.3.2 str2[0:6:-1]
- 步級爲負數,表示提取方向從右到左
- 步級爲1,表示每跨步1個元素提取
- start 爲 0,stop 爲 6
start 元素在 stop 元素的左邊,但提取方向卻是從右到左,無法切片,因此最終結果爲空字符串。
這樣 [0:6:-1] 的寫法當然是不合理的,這只是在我嘗試理解切片過程中隨機做的一些實驗
2.3.3 str2[2:-1:2]
- 步級爲正數,表示提取方向從左到右
- 步級爲2,表示每跨步2個元素提取
- start爲2,從元素 'c' 開始
- stop 爲-1,表示元素'4',用正數表示座標則爲 7
轉換後坐標從 [2, 7),步級爲2,因此結果爲:
print(str2[2:-1:2]) # c13
小結
只是一點小小理解和領悟,就不特意總結了,各位看官自己理解即可。