1. 程式人生 > >Python 賦值、淺拷貝和深度拷貝

Python 賦值、淺拷貝和深度拷貝

前言:
在建立二維陣列時,遇到了list * n—>n shallow copies of list concatenated, n個list的淺拷貝的連線的情況

賦值、淺拷貝和深度拷貝

  • 賦值:是物件的引用
  • 淺拷貝(copy):拷貝父物件,不會拷貝物件的內部的子物件
  • 深拷貝(deepcopy): copy 模組的 deepcopy 方法,完全拷貝了父物件及其子物件。
  • 拷貝即是開闢一塊新的記憶體空間,把被拷貝物件中的值複製過去

注意:

  • 我們尋常意義的賦值就是深copy,即將被複制物件完全再複製一遍作為獨立的新個體單獨存在。所以改變原有被複制物件不會對已經複製出來的新物件產生影響。
  • 而淺拷貝並不會產生一個獨立的物件單獨存在,他只是將原有的資料塊打上一個新標籤,所以當其中一個標籤被改變的時候,資料塊就會發生變化,另一個標籤也會隨之改變。

  • 對於簡單的 object,用 shallow copy(淺拷貝) 和 deep copy(深拷貝) 沒區別
  • 對於複雜的 object, 如 list 中套著 list 的情況,shallow copy 中的 子list,並未從原 object 真的「獨立」出來。也就是說,如果你改變原 object 的子 list 中的一個元素,你的 copy 就會跟著一起變。這跟我們直覺上對「複製」的理解不同。
  • ps:何為簡單的 object、複雜的object,暫時未找到合適的定義。那就從例項出發吧

簡單的 object的例項說明:

import copy
a = [1, 2, 3]
b = a                  # 賦值,傳物件的引用
c = copy.copy(a)       # 物件拷貝,淺拷貝
d = copy.deepcopy(a)   # 物件拷貝,深拷貝
print '第一次輸出:', a, b, c, d
a[0] = 0               # 修改物件
print '第二次輸出:', a, b, c, d

輸出結果:

第一次輸出: [1, 2, 3]
[1, 2, 3] [1, 2, 3] [1, 2, 3] 第二次輸出: [0, 2, 3] [0, 2, 3] [1, 2, 3] [1, 2, 3]

可以驗證->對於簡單的 object,用 shallow copy(淺拷貝) 和 deep copy(深拷貝) 沒區別。
c,d在拷貝時,開闢了一片新的記憶體空間,所以即便a發生變化,也不會影響c,d。

複雜的 object的例項說明:

a2 = [1, 2, [3, 4]]
b2 = a2
c2 = copy.copy(a2)
d2 = copy.deepcopy(a2)
print '第一次輸出:', a2, b2, c2, d2
a2[0] = 0
print '第二次輸出:', a2, b2, c2, d2
a2[2].append(5)
print '第三次輸出:', a2, b2, c2, d2

輸出結果為:

第一次輸出: [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]]
第二次輸出: [0, 2, [3, 4]] [0, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]]
第三次輸出: [0, 2, [3, 4, 5]] [0, 2, [3, 4, 5]] [1, 2, [3, 4, 5]] [1, 2, [3, 4]]

ps:參考連結
http://blog.csdn.net/qq_32907349/article/details/52190796