Python 切片知識整理

知乎問答之 Python 切片

這是一個知乎問答的補充。原問題是python中字符串 s[ : -1]是什麼意思?,當時回答的內容只是對問題本身的簡單回答,對 Python 切片中的重要信息是有所忽略的。如果以slice對象的方式進行切片的話,其語法是這樣的:slice(start, stop[, step]),在原回答中把重要的step給忽略掉了,當然,題主也沒有問到。但仍然很有必要把 Python 切片中的重要信息給補充上。所以,在這裏重新整理一下 Python 切片相關知識,主要參考 Python 官方文檔、博客文章、以及 Python 書籍《Python 編程快速上手 讓繁瑣工作自動化》和《Python 編程無師自通 專業程序員的養成》。

切片

切片是:將一個可迭代對象中元素的子集,創建爲一個新的可迭代對象。可迭代對象包括所有序列類型,如基本序列類型:list, tuplerange 對象,以及特別定製的附加序列類型,strbytes。利用 Python 的切片功能可實現對序列的提取、倒序、淺複製和修改、刪除元素的操作。

切片的實現方法

要實現切片有兩種方法,一是索引擴展(Extending Indexing)的方式;二是slice對象的方式。語法如下所示:

索引擴展(Extending Indexing)

sequence [start:stop[:step]]

start
Optional. Starting index of the slice. Defaults to 0.
stop
Optional. The last index of the slice or the number of items to get. Defaults to len(sequence).
step
Optional. Extended slice syntax. Step value of the slice. Defaults to 1.

slice對象,其實方括號(下標/索引)標記在內部使用的就是 slice 對象。

sequence [slice(start, stop[, step])]

序列元素訪問複習——索引

在開始切片之前,讓我們先複習一下序列元素的訪問。切片的其中一種方法是索引擴展(Extending Indexing),那麼要訪問序列的元素可以用索引,其實切片也是訪問元素的一種,區別在於切片是返回序列,而索引是返回單個元素。

序列索引只能是整數,不能是浮點值。不然將導致 TypeError 錯誤。序列訪問支持負數索引,即:可用來從右向左查找,可迭代對象中元素的索引(必須是一個負數)。整數值 −1 指的是 列表中的最後一個索引,−2 指的是列表中倒數第二個索引,以此類推,在這裏重點注意,負數索引是向後查找,從右往左的,切片同樣支持負數。如下圖:
列表索引可用負數表示,圖片來自 GeeksforGeeks 網站的文章《String Slicing in Python》中的配圖

正式開始切片

切片時包含起始索引位置的元素,但不包括結束索引位置的元素,即[start,stop)。當start + 1 == stop時返回一個元素;當start == stop時返回一個空(empty)序列。

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[1:5] # ['b', 'c', 'd', 'e']
l[1:2] # ['b']
l[4:4] # []

Python 切片
作爲快捷方法,你可以省略切片中冒號兩邊的一個索引或兩個索引。省略第一個索引相當於使用 0,或列表的開始。省略第二個索引相當於使用列表的長度,意味着切片直至列表的末尾。當兩個都省略時,即返回一個原索引的淺複製(shallow copy)。

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[:3] # ['a', 'b', 'c']
l[0:3] # ['a', 'b', 'c']
l[4:] # ['e', 'f', 'g', 'h', 'i']
l[4:len(l)] # ['e', 'f', 'g', 'h', 'i']
l1 = l[:] # 淺複製
l is l1 # False

Python 切片
切片中的負數索引,同樣從右往左向後查找。

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[-7:-2] # ['c', 'd', 'e', 'f', 'g']
l[2:7] # ['c', 'd', 'e', 'f', 'g']
l[2:-5] # ['c', 'd']
l[-8:] # ['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[:-1] # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

Python 切片
Python 切片負數向後查找示意圖,圖片來自 LearnByExample.org 文章《Python List Slicing》配圖

到現在爲止,還沒有爲切片設定step值,其實是在使用默認值,默認值爲1,即每次移動一個序列元素。如果想要跳過一些元素,就可以顯式設定step的值。

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[2:7:2] # ['c', 'e', 'g']

Python 切片

同樣的,step也支持負數,也是向後採集的意思。如果setp爲負數,start值必須大於stop,不然將會得到一個空(empty)序列;如果省略start值,相當於從原序列的末尾開始,如果省略stop值,相當於從原序列的開始結束;而如果start值和stop值都省略,並把step值設置爲1的話,將會得到一個反轉的(reversed)序列。

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[6:1:-2] # ['g', 'e', 'c']
l[1:6:-2] # []
l[:6:-1] # ['i', 'h']
l[6::-1] # ['g', 'f', 'e', 'd', 'c', 'b', 'a']
l[::-1] # ['i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

Python 切片

切片除了可以查找序列中的元素之外,還有一些重要的功能就是修改序列/元素、刪除序列元素。

# 修改
l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
l[1:4] = [1, 2, 3] # 修改後結果爲:['a', 1, 2, 3, 'e', 'f', 'g', 'h', 'i']
l[1:2] = [1, 2, 3] # 修改/替換後的結果爲:['a', 1, 2, 3, 2, 3, 'e', 'f', 'g', 'h', 'i']

# 插入
l = ['a', 'b', 'c']
l[:0] = [1, 2, 3] # 插入後結果爲:[1, 2, 3, 'a', 'b', 'c']

l = ['a', 'b', 'c']
l[len(l):] = [1, 2, 3] # 插入後結果爲:['a', 'b', 'c', 1, 2, 3]

l = ['a', 'b', 'c']
l[1:1] = [1, 2, 3] # 插入後結果爲:['a', 1, 2, 3, 'b', 'c']

# 刪除
l = ['a', 'b', 'c', 'd', 'e']
l[1:5] = [] # 刪除後結果爲:['a']

# 還可以用 del 語句刪除序列中的部分元素
l = ['a', 'b', 'c', 'd', 'e']
del l[1:5] # 刪除後結果爲:['a'],效果一樣

Python 切片

以上都是**索引擴展(Extending Indexing)**的方法實現切片,現在再來看看slice對象。同樣的,可以爲其指定start值和stop值,step是一個可選參數,默認是1。要注意的是slice對象可以只給一個參數,這時就相當於[:stop],如果把這個參數設爲None就相當於[:]

l = ['a', 'b', 'c', 'd', 'e']
s = slice(1, 5, 2) # slice(1, 5, 2)
s = slice(1, 5) # slice(1, 5, None)
s = slice(5) # slice(None, 5, None)
s = slice(None) # slice(None, 5, None)
s = slice(None) # slice(None, None, None)

Python 切片
關於 Python 切片基本就整理到此,初學者使用切片可能容易出錯。需要記住的是,負數從右向左查找;切片時包含起始索引位置的元素,但不包括結束索引位置的元素,即[start,stop);當你的stop不是預期時,可以設置爲stop + 1或省略,尤其是step爲負數的情況下;切片中的 index不會發生list index out of range的錯誤。以上可能有錯漏的地方,歡迎指正。作爲非大神,菜鳥一隻的我,拍磚也懇請輕拍。

這次的 Python 切片整理是源於一個知乎問答,python中字符串 s[ : -1]是什麼意思?,當時主要是摘錄了兩本書的相關章節內容,後面再慢慢搜索整理、補充。其實讀書無論是對於新手還是老司機都是學習的好方法,這不,前段時間從阮一峯先生博客看到一個資源鏈接,於是也把裏面的書單給整理出來了,可能是因爲都是好書吧,基本上都能找到對應的中文版本。這其中還有兩本免費的英文原版書,《Python Programming: An Introduction to Computer Science 》和《Learning With Python: How to Think Like a Computer Scientist》。有興趣的可以稍作移步瞭解一下,就在知乎專欄文章上:自學 Python 可以選擇哪些入門書籍,這當然也是源於一個知乎問答的整理自學Python可以選擇哪些入門書籍?

Note:這也是一篇知乎恰飯稿,和上一篇知乎問答:如果你去擺地攤,賣什麼商品最合適?性質類似。原恰飯回答地址在此:知乎問答之 Python 切片整理

參考

Python 官方文檔-術語表 slice

Python 官方文檔-Python 標準庫 內置函數 slice()

Python 官方文檔-Python 語言參考 del 語句

GeeksforGeeks 網站文章《String Slicing in Python》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章