關於 Python 字串切片的小領悟

2023-10-20 21:00:47

1. 什麼是 Python 字串切片?

例如存在字串 str2 = 「abcd1234" ,有以下簡單的切片應用。

str2[0] # a
str2[0:3] # abc
str2[0:6:2] # ac1

有 3 種形式的切片:

  1. string[index]: 獲取字串特定下標字元
  2. string[start, stop]: 獲取從 start 座標到 stop 座標的字串,注意左閉右開,既 [start, stop) 範圍座標的字串
  3. string[start, stop, step]: 獲取從 start 座標到 stop 座標的字串,且一次提取間隔為 step

上面都是一些基礎的應用,在此之上,還有高階的特性:

  1. 座標為空則預設(提取方向的)開頭或者結尾,步級(step)為空則預設為1
  2. 不管是座標還是步級(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 座標正負的含義

如上圖所示,

  1. 以正數表示座標,則座標是從左到右,從 0 開始計數
  2. 以負數表示座標,則座標是從右到左,從 -1 開始計數
  3. 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. 步級為負數,表示提取方向從右到左
  2. 步級為1,表示每跨步1個元素提取
  3. start 為空,則預設為字串提取方向的最開始
  4. end 為空,則預設為字串提取方向的最後

因此最終結果如下,起到個倒序的效果:

print(str2[::-1]) # 4321dcba

2.3.2 str2[0:6:-1]

  1. 步級為負數,表示提取方向從右到左
  2. 步級為1,表示每跨步1個元素提取
  3. start 為 0,stop 為 6

start 元素在 stop 元素的左邊,但提取方向卻是從右到左,無法切片,因此最終結果為空字串。

這樣 [0:6:-1] 的寫法當然是不合理的,這只是在我嘗試理解切片過程中隨機做的一些實驗

2.3.3 str2[2:-1:2]

  1. 步級為正數,表示提取方向從左到右
  2. 步級為2,表示每跨步2個元素提取
  3. start為2,從元素 'c' 開始
  4. stop 為-1,表示元素'4',用正數表示座標則為 7

轉換後坐標從 [2, 7),步級為2,因此結果為:

print(str2[2:-1:2]) # c13

小結

只是一點小小理解和領悟,就不特意總結了,各位看官自己理解即可。