Python 直接賦值、淺拷貝和深度拷貝解析
阿新 • • 發佈:2022-03-13
1. 直接賦值
在Python中,物件賦值實際上是物件的引用。當建立一個物件,然後把它賦值給另外一個變數的時候,Python並沒有拷貝這個物件,而只是拷貝這個物件的引用,並不會開闢新的記憶體空間。
a = [1, 2, [1, 2]] b = [1, 2, [1, 2]] c = a # 判斷以下結果 a == b 返回 True a == c 返回 True b == c 返回 True a is b 返回 False b is c 返回 False a is c 返回 True # 此時修改a的值,c的值也會跟著改變 a.append(3) print(a) print(b) print(c) 輸出: a: [1, 2, [1, 2], 3] b: [1, 2, [1, 2]] c: [1, 2, [1, 2], 3]
解析:'相等' 和 '相同'是不一樣的
- ==是比較運算子,用來比較物件值是否相同,若相等返回True, 否則返回False
- is是判斷是否為同一個物件,即物件記憶體地址是否相同,若相同返回True,否則返回False
2. 淺拷貝
在Python中,淺拷貝就是拷貝了父物件,但是不會拷貝物件內部的子物件,其內容是原物件的引用。
淺拷貝要分兩種情況進行討論:
- 當淺拷貝是不可變物件(字串,元組,數值型別)時和直接賦值情況一樣,物件的id與淺拷貝對應的id相同
- 當淺拷貝是可變物件(列表,字典,集合)時:
- 複製的物件無複雜子物件,原來值的改變並不會有影響淺拷貝的值,同時淺拷貝複製的值改變也不會影響原來的值,原來物件的id與淺拷貝度物件id不同
- 複製的物件中有複雜子物件(例如列表中的一個子元素是一個列表),如果不改變其中複雜元素,淺拷貝的值改變不會影響原來的值,但是改變原來的值的複雜子物件的值會影響淺拷貝的值
3. 深拷貝
和淺拷貝對應,深拷貝拷貝物件的所有元素,包括多層巢狀的元素,深拷貝出來的物件是一個全新物件,不再和原來的物件有任何關聯
import copy a = [1, 2, 3, [4, 5], 6] b = a c = copy.copy(a) d = copy.deepcopy(a) b.append(10) c[3].append(11) d[3].append(12) print("a is:{}, b is:{}, c is:{}, d is:{}".format(a, b, c, d)) # 輸出: a is:[1, 2, 3, [4, 5, 11], 6, 10], b is:[1, 2, 3, [4, 5, 11], 6, 10], c is:[1, 2, 3, [4, 5, 11], 6], d is:[1, 2, 3, [4, 5, 12], 6]
解析:
如圖所示:
- 由於b是a的賦值,所以b的改變會導致a也改變
- c是a的淺拷貝,c[3]是一個可變物件,所以改變c[3]值會影響a的值
- d是a的深拷貝,d[3]的改變並不影響a的值