1. 程式人生 > 其它 >python學習---淺拷貝與深拷貝的關鍵點

python學習---淺拷貝與深拷貝的關鍵點

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 list 
21217408 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