在使用 Python 的時候,你會發現自己在使用 my_list.pop() 來刪除列表的最後一項,以及用 my_dict.pop('key') 刪除字典的項目,無論何種對象,都是在使用 .pop()。
有時 pop() 感覺就像是可以附加到任何對象上的 萬能實例方法。那麼這 pop() 方法的本質是什麼呢?
1. 'pop()' 不是一個
簡單來說,list 的 pop() 和 dict 的 pop() 名字相同,但實際上是完全不同的方法。
-
list類別為列表定義了專屬的pop()方法。 -
dict類別同樣為字典定義了專屬的pop()方法。 -
set類別也是如此。
擁有相同名字的方法的不同對象之所以能這樣,是因為 Python 的物件導向特性之一——多型性 (Polymorphism)。名稱 'pop' 只是共享了 "從資料結構中提取並返回一個項目 (pop)" 的傳統意義。
2. 各類別的 pop() 不同的運作方式
雖然名稱相同,但其運作方式並不相同。每個類別都是針對自己的資料結構實現了 pop()。
1. list.pop([index])
-
運作: 從列表中 移除並返回某個特定索引 (index) 的項目。
-
特性: 如果沒有指定索引,預設為
-1,將移除 最後一項。這與堆疊(Stack)資料結構的 'pop' 操作相同。 -
範例:
my_list = ['a', 'b', 'c']
# 不指定索引(移除最後一項 'c')
last_item = my_list.pop()
print(f"返回的值: {last_item}, 剩餘列表: {my_list}")
# 輸出: 返回的值: c, 剩餘列表: ['a', 'b']
# 指定索引 0(移除 'a')
first_item = my_list.pop(0)
print(f"返回的值: {first_item}, 剩餘列表: {my_list}")
# 輸出: 返回的值: a, 剩餘列表: ['b']
2. dict.pop(key[, default])
-
運作: 從字典中 移除並返回對應某個特定鍵 (key) 的項目 (鍵值對)。
-
特性: 不同於
list.pop(),此方法必須傳遞 鍵 (key),而不是索引。如果鍵不存在且給定了default值,則返回該值;如果沒有給定default值,將引發KeyError。 -
範例:
my_dict = {'apple': 1, 'banana': 2}
# 移除 'apple' 鍵
item = my_dict.pop('apple')
print(f"返回的值: {item}, 剩餘字典: {my_dict}")
# 輸出: 返回的值: 1, 剩餘字典: {'banana': 2}
# 嘗試刪除不存在的鍵 ('grape')(返回 default 值 99)
default_item = my_dict.pop('grape', 99)
print(f"返回的值: {default_item}, 剩餘字典: {my_dict}")
# 輸出: 返回的值: 99, 剩餘字典: {'banana': 2}
3. set.pop()
-
運作: 從集合 (set) 中 隨機移除一個項目並返回該項目。
-
特性: 集合是無序的資料結構,因此無法預測將移除哪個項目。
pop()不接受任何參數。 -
範例:
my_set = {10, 20, 30}
# 隨機移除一項(不知結果為何)
item = my_set.pop()
print(f"返回的值: {item}, 剩餘集合: {my_set}")
# 可能的輸出 1: 返回的值: 10, 剩餘集合: {20, 30}
# 可能的輸出 2: 返回的值: 20, 剩餘集合: {10, 30}
3. 為何看起來 "無所不在"
我們在使用 pop() 時,覺得它像 "實例方法",這是正確的。pop() 確實是每個對象(實例)所擁有的方法。
看似 obj.pop() 的情況並不意味著 pop() 是全局函數,或是定義在所有對象的父類別中的方法。當 Python 調用 obj.method() 時,會動態檢查 obj 這個對象是否擁有名稱為 method 的屬性(方法)。
-
my_list是list類的實例,list類定義了pop。 -
my_dict是dict類的實例,dict類也定義了pop。
因此 my_list.pop() 和 my_dict.pop() 都可以正常工作。
如果在未定義 pop() 方法的對象上嘗試調用,結果會如何?如預期,會引發 AttributeError。以元組為例。
# 元組(tuple) 不能更改項目,因此沒有 pop() 方法。
my_tuple = (1, 2, 3)
# AttributeError: 'tuple' object has no attribute 'pop'
my_tuple.pop()

總結
-
pop()不是 Python 的全局函數或共通方法。 -
list、dict、set等 都是各自容器類別獨立定義的方法。 -
它們同名是因為 "提取數據並返回" 的 習慣性 (convention) 意義。
-
由於每個類別的運作方式不同,
list依據索引,dict依據鍵,set隨機移除項目。
目前沒有評論。