python學習---淺拷貝與深拷貝的關鍵點
阿新 • • 發佈:2022-03-14
1. python 可變與不可變物件
可變物件:指向地址不變,內容改變(原指向記憶體地址修改內容)
不可變物件:指向地址改變,內容改變(原指向地址不能改,重新開闢新的記憶體地址保持,所以地址與內容都發生改變)
- 可變物件:list dict set
- 不可變物件:tuple string int float bool
2. 淺拷貝與深拷貝
第一個注意點:
- 對於不可變物件來說,賦值操作其實就可以滿足上面說的實際應用場景
- 所以!後面要講的淺拷貝、深拷貝對於不可變物件來說,和賦值操作是一樣的效果!
- 記住!淺拷貝、深拷貝只針對可變物件,即列表、集合、字典!
3.淺拷貝: copy
一句話概括: 淺拷貝會建立一個新物件,該新物件儲存原始元素的引用,指向的物件並不是同一個
- 淺拷貝後的值是相同的
- 淺拷貝後的會產生一個新的物件
3.1.修改列表內的可變元素
import copy old = [[1, 2], [3, 4]] new = copy.copy(old) print("old list", id(old)) old.append([5, 6]) old[1][1] = 44 print("Old list:", old, "id is :", id(old)) print("New list:", new, "id is :", id(new)) 執行結果: old list21217408 Old list: [[1, 2], [3, 44], [5, 6]] id is : 21217408 New list: [[1, 2], [3, 44]] id is : 21218128
淺拷貝會開闢新的記憶體地址,新的變數會指向新記憶體地址
列表裡面的元素(可變元素)地址則指向同一個記憶體地址,修改舊的列表元素,則兩個都發生改變
3.2 修改列表內的不可變物件元素
import copy old = [1, 2, "string", (1, 2,)] new = copy.copy(old) print("old list", id(old)) old.append([5, 6]) old[1] += 22 old[2] += "s" old[3] += (44,) print("Old list:", old, "id is :", id(old),id(old[3])) print("New list:", new, "id is :", id(new),id(new[3])) 執行結果: old list 30941232 Old list: [1, 24, 'strings', (1, 2, 44), [5, 6]] id is : 30941232 30884088 New list: [1, 2, 'string', (1, 2)] id is : 30887848 29210144
對於不可變物件,列表物件與列表裡面的元素都不會指向相同的地址
4. 深拷貝:deepcopy
- 建立一個新物件,且儲存的物件引用也是新的
- 深,意味著會把所有子元素物件也複製生成一個新物件
import copy old = [[1, 2], [3, 4]] new = copy.deepcopy(old) print("old list", id(old)) old.append([5, 6]) print("Old list:", old, "id is :", id(old),id(old[1])) print("New list:", new, "id is :", id(new),id(new[1])) 執行結果: old list 27705512 Old list: [[1, 2], [3, 4], [5, 6]] id is : 27705512 27667512 New list: [[1, 2], [3, 4]] id is : 27706232 27705872
- 兩個變數儲存了不同的物件引用
- 可變物件元素(子物件)的記憶體地址也是不同的
參考文章:https://www.cnblogs.com/poloyy/p/15084277.html