程式中常常需要複製一個物件, 依思路應該是這樣的
a = [1, 2, 3] b = a # [1, 2, 3] print b
已經複製好了,但是現在得改一下第一個元素的值把它改成5
b[0] = 5 # [5, 2, 3] print b # [5, 2, 3] print a
我改變了b的第一個元素的值,但是a的值也改變了,這是因為python中的=是引用.a和b指向的是相同的列表,所以改變列表會出現以上的結果.
解決方法是切片操作
a = [1, 2, 3] b = a[:] b[0] = 4 # [1, 2, 3] # [4, 2, 3] print a print b
但是在巢狀清單的時候呢,試試看
a = [[1,2,3], 4, 5] b = a[:] b[1] = 0 # [[1,2,3], 4, 5] # [[1,2,3], 0, 5] print a print b
恩!沒什麼問題,在試試嵌套列表元素
a = [[1,2,3], 4, 5] b = a[:] b[0][0] = 5 # [[5,2,3], 4, 5] # [[5,2,3], 4, 5] print a print b b = a[:]
a的值還是改變了,切片複製只對該物件進行拷貝不會對子元素進行拷貝
copy 模組
copy模組用於物件的拷貝操作。這個模組非常簡單,只提供了兩個主要的方法: copy.copy 與 copy.deepcopy ,分別表示淺複製與深複製。什麼是淺複製,什麼是深複製,網路上有一卡車一卡車的資料,這裡不作詳細介紹。複製操作只對複合物件有效。用簡單的例子來分別介紹這兩個方法。
淺複製只複製物件本身,沒有複製該物件所引用的物件。
#coding=gbk import copy l1 = [1, 2, [3, 4]] l2 = copy.copy(l1) print l1 print l2 l2[2][0] = 50 print l1 print l2
結果:
[1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [50, 4]] [1, 2, [50, 4]]
同樣的程式碼,使用深複製,結果就不一樣:
import copy l1 = [1, 2, [3, 4]] l2 = copy.deepcopy(l1) print l1 print l2 l2[2][0] = 50 print l1 print l2
結果:
[1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [50, 4]]
改變copy的預設行為
定義類別的時候,定義__copy__和__deepcopy__方法,可以改變copy的預設行為。下面是一個簡單的例子:
class CopyObj(object): def __repr__(self): return "CopyObj" def __copy__(self): return "Hello" obj = CopyObj() obj1 = copy.copy(obj) print obj print obj1
結果:
CopyObj Hello