對於每個 Python 程式設計師來說,無論是在資料科學和機器學習領域,還是在軟體開發領域,Python 切片操作都是最高效、最通用、最強大的操作之一。Python 切片語法允許提取和修改資料結構,如列表、字串、元組、陣列、Pandas 資料幀,甚至位元組序列。無論我們是要在 Python 中提取列表切片的一部分,還是使用字串切片操作字元,或者只是想簡化工作流程,切片都提供了一種簡潔的資料處理方式,而無需使用複雜的迴圈或手動索引。在本 Python 切片教程中,我們將深入探討 Python 切片操作的工作原理,並學習如何在程式和工作流中有效地使用它們。
什麼是 Python 中的切片操作?
切片意味著切割。同樣,在 Python 中,它意味著透過指定索引範圍來訪問或提取序列(如字串、列表、元組或陣列)的子序列(部分)。Python 中的切片操作涉及在方括號內使用冒號運算子 [:] 。基本語法包括
[START:END:STEP]START:Start 是開始切片的索引。END:End 是執行操作的索引點,即不包含在操作中。STEP: Step 是增量索引。預設值為 1,即輸出整個序列。如果 step=2,則將列印每個交替值。
為什麼使用切片法?
切片是一種重要的方法,因為它允許我們簡潔地訪問和運算元據,使程式碼更具可讀性,並在不同的資料結構中具有通用性。例如
不使用切片的迭代
lst = [1, 2, 3, 4, 5] sublist = [] for i in range(1, 4): sublist.append(lst[i]) print(sublist)
切片迭代
lst = [1, 2, 3, 4, 5] sublist = lst[1:4] print(sublist)
輸出:[2, 3, 4]
Python中的切片方法
基本上,Python 提供了兩種不同的切片方法。一種是 [start: end: step] 函式,另一種是 .slice(start, stop, step) 函式。在本節中,我們將首先了解這些切片操作的語法,然後探討我們可以在 Python 中執行的主要切片型別。
1. 使用 [start: end: step]
這是對輸入序列的不同部分執行切分操作的最常用方法。
使用索引 [:] 切片示例
mixed_data = [10, "apple", 3.14, "banana", 42, "cherry"] # Slice from index 1 to 4 print(mixed_data[1:4]) print(20*"--") # Slice the list from the start to index 3 print(mixed_data[:3]) print(20*"--") # Slice every 2nd element print(mixed_data[::2])
['apple', 3.14, 'banana']---[10, 'apple', 3.14]---[10, 3.14, 42]
2. 使用 Python slice() 函式
slice 函式允許您建立一個將應用於序列的 slice 物件。當您想儲存切片規範並將其應用於多個序列時,該功能會有所幫助。
.slice() 的語法
slice(start, stop, step)
start:切片的起始索引(包含)。stop:切片的停止索引(不包含)。step:step 或 stride(每一步後索引的增量,可選)。
使用 slice() 分割。示例:
text = "Hello, world!" # Create a slice object to get the first 5 characters s = slice(0, 5) # Apply the slice object to the string print(text[s]) # Output: "Hello"
每三個元素切一次
mixed_data = [10, "apple", 3.14, "banana", 42, "cherry"] s = slice(None, None, 3) # Apply the slice object to the list print(mixed_data[s]) # Output: [10, 'banana']
從索引 2 開始切到末端
s = slice(2, None) # Apply the slice object to the list print(mixed_data[s]) # Output: [3.14, 'banana', 42, 'cherry']
按相反順序切片
s = slice(None, None, -1) # Apply the slice object to the list print(mixed_data[s]) # Output: ['cherry', 42, 'banana', 3.14, 'apple', 10]
現在我們來看看 Python 中主要的切片操作型別
1. 基本切片
基本切分是指使用語法 [start: end: step] 提取字串、列表或元組等資料型別的子序列。它是 Python 中的一個基本工具,能讓我們輕鬆檢索子序列。它還適用於多種資料型別,因此是一種通用技術。
- List 切片
numbers = [10, 20, 30, 40, 50, 60] # Slice from index 1 to index 4 (exclusive) print(numbers[1:4]) # Output: [20, 30, 40]
- String 切片
text = "Hello, world!" # Slice from index 7 to index 12 (exclusive) print(text[7:12]) # Output: "world"
- Tuple 切片
numbers_tuple = (1, 2, 3, 4, 5, 6) # Slice from index 2 to index 5 (exclusive) print(numbers_tuple[2:5]) # Output: (3, 4, 5)
2. 省略‘start’, ‘stop’, 或‘step’
在切片中省略開始、停止和步長可以讓使用者使用預設值。
- 省略開始預設為序列的開始。
- 省略停止表示切片一直進行到結束。
- 省略步長則預設步長為 1。
省略這些部分可以使程式碼更簡潔、更靈活。它使你能夠建立動態和通用的切片,而無需明確定義所有引數。
使用切片修改列表
numbers = [10, 20, 30, 40, 50, 60] # Omitting start, slice from the beginning to index 4 (exclusive) print(numbers[:4]) # Output: [10, 20, 30, 40] # Omitting stop, slice from index 2 to the end print(numbers[2:]) # Output: [30, 40, 50, 60]
空切片
numbers_tuple = (1, 2, 3, 4, 5, 6) # Omitting start and step, slice the whole tuple print(numbers_tuple[:]) # Output: (1, 2, 3, 4, 5, 6)
刪除元素
numbers = [2,4,5,12,64,45] numbers[1:4] = [] print(numbers) # Output: [2,64,45]
3. 負切片
負索引允許從序列末尾開始計數。在負索引中,-1 表示最後一個元素,-2 表示倒數第二個元素。當你需要訪問序列末尾的元素時,它可以幫助你。
訪問最後一個元素
numbers = [10, 20, 30, 40, 50, 60] # Slice at the last index print(numbers[-1]) # Output: [60]
反轉字串
original_string = "hello" reversed_string = original_string[::-1] print(reversed_string) # Output: "olleh"
4. 使用步長進行切片
步長引數可以指定元素之間的間隔,這在處理或取樣資料時非常有用。如上圖所示,負步長可以很容易地逆轉序列,這使得逆轉整個資料變得非常簡單方便。
每隔 2 個元素切片
numbers = [10, 20, 30, 40, 50, 60] # Slice with step 2, picking every second element print(numbers[::2]) # Output: [10, 30, 50]
混亂的步長行為
numbers = [10, 20, 30, 40, 50, 60] # Slice at last index print(numbers[::-3]) # Output: [60,30]
5. 使用 None 進行切片
在切片中,None 可用於表示開始、停止和結束的預設值。使用 None 可以使程式設計更靈活、更清晰。這是一種無需手動定義即可應用預設切片行為的方法。
省略使用 None
numbers = [10, 20, 30, 40, 50, 60] # Slice every 2nd element using slice(None, None, 2) s = slice(None, None, 2) print(numbers[s]) # Output: [10, 30, 50]
6. 越界切片
當您嘗試對一個序列進行超出其邊界的切分時(無論是使用大索引還是使用超出範圍的 -ve 索引),Python 不會引發任何錯誤,只會返回最大的有效切分,而不用擔心異常。
numbers = [10, 20, 30, 40, 50, 60] # Slice beyond the length of the list print(numbers[4:15]) # Output: [50, 50]
超長切片
text = "Hello, world!" # Slice beyond the length print(text[15:55]) # Output: no output
7. NumPy陣列切片
在 NumPy 中,切片與 Python 的基本切片類似。此外,NumPy 是專為科學計算而設計的,也允許更快的資料操作。這有助於進一步支援更先進、更高效的大型資料集操作。切片使 NumPy 能夠訪問子陣列並高效地修改它們(即允許我們修改子陣列)。
切片一維陣列
import numpy as np # Create a 1-D NumPy array arr = np.array([10, 20, 30, 40, 50, 60]) # Slice from index 1 to index 4 (exclusive) print(arr[1:4]) # Output: [20 30 40]
與基本的切片一樣,它允許我們從索引 1 到 4(排他)對陣列進行切片,就像普通的 Python 切片一樣。它還允許在陣列中執行上面討論過的所有其他操作。
# Slice every second element from the array print(arr[::2]) # Output: [10 30 50]
切片多維陣列
# Create a 2-D NumPy array (matrix) arr_2d = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]]) # Slice from row 1 to row 2 (exclusive), and columns 1 to 2 (exclusive) print(arr_2d[1:2, 1:3]) # Output: [[50 60]]
8. Pandas資料幀切片
Pandas DataFrames 是二維標籤資料結構,也支援切片操作。它允許透過 .loc() 和 .iloc() 對資料點進行切分。此外,Pandas 還支援布林索引。
對資料幀本身進行切片可以高效地過濾和處理大型資料集。它允許使用條件選擇資料子集,使其成為資料分析和機器學習的重要工具。
使用行索引(.iloc)進行切片
import pandas as pd # Create a DataFrame df = pd.DataFrame({ 'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50] }) print(df) # Output # A B # 0 1 10 # 1 2 20 # 2 3 30 # 3 4 40 # 4 5 50 # Slice the first three rows (exclusive of the fourth row) print(df.iloc[:3]) # A B # 0 1 10 # 1 2 20 # 2 3 30
在這裡,.iloc(3) 會切分 DataFrame 的前 3 行(索引 0 至 2)。
使用列名(.loc)切片
# Create a DataFrame df = pd.DataFrame({ 'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50] }) print(df) # Output # A B # 0 1 10 # 1 2 20 # 2 3 30 # 3 4 40 # 4 5 50 print(df.loc[df['A'] > 2]) # Output: # A B # 2 3 30 # 3 4 40 # 4 5 50
.loc 允許使用列名或索引(如 False)對標籤進行切分。在這裡,我們根據列“A”的值必須大於 2 的條件進行切分。
9. 位元組序列切片
Python 提供了位元組序列(如 bytes 和 bytearray),它們與列表、字串或陣列一樣支援切片。當我們使用二進位制資料型別時,位元組序列就會出現,而切片可以讓您輕鬆高效地提取二進位制資料的相關部分。
切分位元組物件
byte_seq = b'Hello, world!' # Slice from index 0 to index 5 (exclusive) print(type(byte_seq)) print(byte_seq[:5]) # Output: <class 'bytes'>, b'Hello'
分割位元組陣列(可變位元組)
byte_arr = bytearray([10, 20, 30, 40, 50, 60]) # Slice from index 2 to index 5 (exclusive) print(byte_arr[2:5]) # Output: bytearray(b'2\x1e<')
在這裡,輸出值與 ASCII 字元相對應。當輸出不在可列印範圍內時,就會出現這種情況。因此,bytearray(b’2\x1e<‘) 是輸出結果,因為它以更易於人類閱讀的形式表示這些位元組值。
print(list(byte_arr[2:5])) # Output: [30, 40, 50] # Ouput: [30,40,50]
在Python中使用切分操作的好處
在 Python 中使用切分操作有很多好處,其中包括
- 效率高:切片操作可以快速訪問較大資料集中的所需子序列,而無需迴圈。
- 簡潔:它使資料操作的程式碼更簡潔、更易讀。
- 靈活性:在 NumPy 和 Pandas 等庫的幫助下,多維資料切分為資料預處理提供了一種高效的方法。
- 高效記憶體:切片處理經過了效能最佳化。此外,Python 的內部機制確保了切片操作的快速性和記憶體效率,這與手動索引不同,手動索引需要大量的手動編碼並會增加記憶體使用量。
使用切分操作時應避免的事項
以下是在 Python 中使用切分操作時應避免的幾件事。
- 超出索引邊界:在 Python 中,超出序列長度的切分不會導致任何錯誤。然而,這會導致不必要的結果,尤其是在處理較大的資料集時。
- 混淆索引和切片語法:切片語法涉及 sequence[start:stop:end],但選擇我們想要的元素的索引/位置也會得到想要的元素。
- 不考慮可變性的切分:切分可用於修改序列,但使用時必須考慮所處理的資料型別是否支援可變性。例如,列表和位元組陣列是可變的;而字串、元組和位元組則是不可變的。因此無法透過切片直接修改它們。
- 使用無效步驟值進行切片:在使用切片時,還必須考慮步長,因為步長將決定中間跳過多少個點。但使用無效值可能會導致意想不到的結果,造成操作效率低下。
小結
Python 中的切片是一種高效而強大的方法,它允許您有效地訪問和操作 Python 資料型別,如列表、字串、元組、NumPy 陣列和 Pandas DataFrames。因此,無論您是對列表進行切片,還是使用 NumPy 處理多維陣列,或者使用 Pandas 處理大型資料集,切片總是能為處理序列提供一種清晰簡潔的方法。掌握了切片,就能編寫出更簡潔、更高效的程式碼,這對每個 Python 程式設計師來說都是必不可少的。
評論留言