在python中,物件賦值實際上是物件的引用。當建立乙個物件,然後把它賦給另乙個變數的時候,python並沒有拷貝這個物件,而只是拷貝了這個物件的引用
針對該列表l1=['a','b','c',['d','e','f']]
一般有三種方法,分別為:拷貝(賦值)、淺拷貝、深拷貝
注意:拷貝/淺拷貝/深拷貝都是針對可變型別資料而言的,id不變值可變,即在原值的基礎上修改,則為可變資料型別;值變id也變,即重新申請乙個空間放入新值,則為不可變資料型別。
如果l2是l1的拷貝物件,則l1內部的任何資料型別的元素變化,則l2內部的元素也會跟著改變,因為可變型別值變id不變。
lt = [1, 2, 3, 4, 5]
lt2 = lt
print(lt)
# 因為列表是可變型別, 所以lt的值變化,lt2值也會跟著變化
print(lt2)
print(id(lt))
print(id(lt2))
結果:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
2304711549576
2304711549576
如果l2是l1的淺拷貝物件,則l1內的不可變元素發生了改變,l2不變;如果l1內的可變元素發生了改變,則l2會跟著改變。
新增值不發生變化
import copy
lt = [100, 200, 300, [400, 500, 600]]
lt2 = copy.copy(lt)
# 沒有變化情況
print(lt)
print(lt2)
結果:
[100, 200, 300, [400, 500, 600], 700]
[100, 200, 300, [400, 500, 600]]
新增值發生變化
import copy
lt = [100, 200, 300, [400, 500, 600]]
lt2 = copy.copy(lt)
# 變化情況
print('id(lt)',id(lt))
print('id(lt[0])', id(lt[0]))
print('id(lt[1])', id(lt[1]))
print('id(lt[2])', id(lt[2]))
print('id(lt[3])', id(lt[3]))
print('*' * 50)
print('id(lt2)',id(lt2))
print('id(lt2[0])', id(lt2[0]))
print('id(lt2[1])', id(lt2[1]))
print('id(lt2[2])', id(lt2[2]))
print('id(lt2[3])', id(lt2[3]))
print('*' * 50)
print(lt)
print(lt2)
結果:(淺拷貝,lt和lt2的id不一樣,lt[-1]和lt[-1]一樣)
id(lt) 1520433324744
id(lt[0]) 140712889544624
id(lt[1]) 140712889547824
id(lt[2]) 1520433550832
id(lt[3]) 1520433324680
id(lt2) 1520715912264
id(lt2[0]) 140712889544624
id(lt2[1]) 140712889547824
id(lt2[2]) 1520433550832
id(lt2[3]) 1520433324680
[100, 200, 300, [400, 500, 600, 700]]
[100, 200, 300, [400, 500, 600, 700]]
如果l2是l1的深拷貝物件,則l1內的不可變元素發生了改變,l2不變;如果l1內的可變元素發生了改變,l2也不會變,即l2永遠不會因為l1的變化而變化。
import copy
lt = [100, 200, 300, [400, 500, 600]]
lt2 = copy.deepcopy(lt)
print('id(lt)',id(lt))
print('id(lt[0])', id(lt[0]))
print('id(lt[1])', id(lt[1]))
print('id(lt[2])', id(lt[2]))
print('id(lt[3])', id(lt[3]))
print('*' * 50)
print('id(lt2)',id(lt2))
print('id(lt2[0])', id(lt2[0]))
print('id(lt2[1])', id(lt2[1]))
print('id(lt2[2])', id(lt2[2]))
print('id(lt2[3])', id(lt2[3]))
print('*' * 50)
print(lt)
print(lt2)
print("*" * 50)
print(lt)
print(lt2)
結果:
id(lt) 1585269859016
id(lt[0]) 140712889544624
id(lt[1]) 140712889547824
id(lt[2]) 1585270085104
id(lt[3]) 1585269858952
id(lt2) 1585552380680
id(lt2[0]) 140712889544624
id(lt2[1]) 140712889547824
id(lt2[2]) 1585270085104
id(lt2[3]) 1585299572040
[100, 200, 300, [400, 500, 600], 70]
[100, 200, 300, [400, 500, 600]]
[100, 200, 300, [400, 500, 600], 70]
[100, 200, 300, [400, 500, 600, 7000]]
拷貝:當lt2為lt的拷貝物件時, lt內可變型別變化,lt2變化;lt內的不可變型別變化,lt2變化(簡單賦值)
淺拷貝:當lt2為lt的拷貝物件時,lt內可變型別變化,lt2變化;lt內不可變型別變化,lt2不變化(copy.copy())
深拷貝:當lt2為lt的拷貝物件時, lt內的可變型別變化,lt2不變化;lt內不可變型別變化,lt2不變化(copy.deepcopy())
注:拷貝/淺拷貝/深拷貝 只針對可變資料型別
python 深淺拷貝案例 python 深淺拷貝
深淺拷貝 對於 數字 和 字串 而言,賦值 淺拷貝和深拷貝無意義,因為其永遠指向同乙個記憶體位址 import copy a1 22255 a2 22255 print id a1 id a2 3428240 3428240 對於字典 元祖 列表 而言,進行賦值 淺拷貝和深拷貝時,其記憶體位址的變化...
python 深淺拷貝
建立乙個寬度為3,高度為4的陣列 mylist 0 3 4 0,0,0 0,0,0 0,0,0 0,0,0 但是當操作mylist 0 1 1時,發現整個第二列都被賦值,變成 0,1,0 0,1,0 0,1,0 0,1,0 list n n shallow copies of list concat...
python深淺拷貝
python 深淺拷貝 shallow copy 和 deep copy 對於乙個列表,列表裡面可以再放入乙個列表 1 若想複製這乙個列表,使用列表的普通的copy 方法,只能拷貝出列表裡表層的元素,而列表裡的列表卻無法拷貝,只能指向前乙個列表.修改拷貝出的列表裡列表裡的元素,原來的列表會發生改變....