1. 程式人生 > 實用技巧 >Python深拷貝和淺拷貝

Python深拷貝和淺拷貝

  • 淺拷貝就是對於一個物件引用的拷貝,而深拷貝就是對物件資源(具體值)的拷貝
  • 對於不可變物件(字串、元組,整型)的修改,需要開闢新的空間,此時id發生改變,而對於可變物件(列表,字典等)的修改,不需要開闢新的空間
  • 淺拷貝後的orilist和copylist中的元素都指向了相同的地址。修改不可變物件的時候,就需要開闢新的空間(地址變了),所以orilist和copylist中的字串內容不一樣。但是對於list,修改orilist中的list物件後,copylist中的list內容也隨之發生了改變。(因為copylist和orlist的list是指向的同一個物件)
  • 深拷貝無論是對於可變物件還是不可變物件,對於orilist的修改都不會影響到deepcopylist中的內容

對於一個可變物件(列表)的例子

注意到 python3 語言, 物件是一個盒子,有具體的地址,而變數名相當於是 "標籤",可以貼在盒子上。

我們需要辨析:nums1 = A 和 nums1[:] = A 的不同之處:

  • nums1 = A # 更改 nums1 這一變數名所指向的物件。讓 nums1 變數指向 A 所指向的物件
  • nums1[:] = A # 對 nums1 指向的物件賦值。把 A 變數指向的物件的值逐個 copy 到 nums1 指向的物件中並覆蓋 nums1 指向的物件的原來值。
# 物件在記憶體中的地址與id一一對應,可以使用 id() 檢視並判斷是否是同一個物件

nums1 = [1,2,4,0,0] 
print(id(nums1)) # 140125129895880

A = [1,2,3,4,5]
print(id(A))     # 140125129856640

nums1[:] = A
print(id(nums1))) # 140125129895880,  仍是原 list 物件, 只不過這一 list 物件的值發生了改變

# 若不執行 nums1[:] = A, 而執行
nums1 = A
print(id(nums1))  # 140125129856640, 不再是之前的那個 list 物件