Python copy() - List 複製
copy() 方法用來建立 list 的淺拷貝(shallow copy)。
基本用法
original = [1, 2, 3]
copied = original.copy()
print(original) # [1, 2, 3]
print(copied) # [1, 2, 3]
# 修改複製的 list 不影響原 list
copied.append(4)
print(original) # [1, 2, 3]
print(copied) # [1, 2, 3, 4]
為什麼需要 copy()
直接賦值只會建立參照,不是複製:
original = [1, 2, 3]
not_a_copy = original # 只是參照同一個 list
not_a_copy.append(4)
print(original) # [1, 2, 3, 4](被影響了!)
print(not_a_copy) # [1, 2, 3, 4]
複製 list 的方法
original = [1, 2, 3]
# 方法 1:copy() 方法
copied1 = original.copy()
# 方法 2:切片
copied2 = original[:]
# 方法 3:list() 建構函數
copied3 = list(original)
# 方法 4:list comprehension
copied4 = [x for x in original]
# 都是獨立的複本
copied1.append(4)
print(original) # [1, 2, 3]
print(copied1) # [1, 2, 3, 4]
淺拷貝(Shallow Copy)
copy() 是淺拷貝,只複製第一層:
original = [[1, 2], [3, 4]]
copied = original.copy()
# 修改第一層沒問題
copied.append([5, 6])
print(original) # [[1, 2], [3, 4]]
print(copied) # [[1, 2], [3, 4], [5, 6]]
# 但內層物件是共用的!
copied[0].append(999)
print(original) # [[1, 2, 999], [3, 4]](被影響了!)
print(copied) # [[1, 2, 999], [3, 4], [5, 6]]
深拷貝(Deep Copy)
使用 copy.deepcopy() 進行深拷貝:
import copy
original = [[1, 2], [3, 4]]
deep_copied = copy.deepcopy(original)
# 修改內層也不會影響原本的
deep_copied[0].append(999)
print(original) # [[1, 2], [3, 4]](不受影響)
print(deep_copied) # [[1, 2, 999], [3, 4]]
實際範例
保存狀態
def save_state(history, current):
history.append(current.copy())
history = []
data = [1, 2, 3]
save_state(history, data)
data.append(4)
save_state(history, data)
data.append(5)
save_state(history, data)
print(history) # [[1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
避免修改原始資料
def process_data(data):
# 複製後處理,避免影響原資料
working_copy = data.copy()
working_copy.sort()
return working_copy
original = [3, 1, 4, 1, 5]
sorted_data = process_data(original)
print(original) # [3, 1, 4, 1, 5](不變)
print(sorted_data) # [1, 1, 3, 4, 5]
函數參數的防禦性複製
def add_item(items, item):
# 建立新 list 而不是修改傳入的
new_items = items.copy()
new_items.append(item)
return new_items
original = [1, 2, 3]
new_list = add_item(original, 4)
print(original) # [1, 2, 3]
print(new_list) # [1, 2, 3, 4]
深拷貝複雜結構
import copy
game_state = {
"players": [
{"name": "Alice", "score": 100, "inventory": ["sword", "shield"]},
{"name": "Bob", "score": 80, "inventory": ["bow"]}
],
"level": 5
}
# 需要深拷貝來完全複製
saved_state = copy.deepcopy(game_state)
# 修改原始狀態
game_state["players"][0]["score"] = 150
game_state["players"][0]["inventory"].append("potion")
print(saved_state["players"][0]["score"]) # 100(不變)
print(saved_state["players"][0]["inventory"]) # ['sword', 'shield'](不變)
常見錯誤
忘記複製
# 錯誤:會修改原 list
def remove_negatives(numbers):
for n in numbers[:]: # 需要先複製
if n < 0:
numbers.remove(n)
return numbers
# 正確:使用 list comprehension 建立新 list
def remove_negatives(numbers):
return [n for n in numbers if n >= 0]
淺拷貝陷阱
# 陷阱:淺拷貝不會複製內層
matrix = [[0] * 3 for _ in range(3)]
row_copy = matrix[0].copy() # 這是淺拷貝
# 但如果是這樣就有問題
matrix = [[0] * 3] * 3 # 三列都是同一個 list!
matrix[0][0] = 1
print(matrix) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
效能考量
- 淺拷貝
copy():O(n) - 深拷貝
deepcopy():O(n × m),其中 m 是巢狀深度
只有在需要時才使用深拷貝,因為它比較慢。