1. 程式人生 > 其它 >Python 直接賦值、淺拷貝和深度拷貝解析

Python 直接賦值、淺拷貝和深度拷貝解析

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]

解析:'相等' 和 '相同'是不一樣的

  1. ==是比較運算子,用來比較物件值是否相同,若相等返回True, 否則返回False
  2. is是判斷是否為同一個物件,即物件記憶體地址是否相同,若相同返回True,否則返回False

2. 淺拷貝

在Python中,淺拷貝就是拷貝了父物件,但是不會拷貝物件內部的子物件,其內容是原物件的引用。
淺拷貝要分兩種情況進行討論:

  • 當淺拷貝是不可變物件(字串,元組,數值型別)時和直接賦值情況一樣,物件的id與淺拷貝對應的id相同
  • 當淺拷貝是可變物件(列表,字典,集合)時:
    1. 複製的物件無複雜子物件,原來值的改變並不會有影響淺拷貝的值,同時淺拷貝複製的值改變也不會影響原來的值,原來物件的id與淺拷貝度物件id不同
    2. 複製的物件中有複雜子物件(例如列表中的一個子元素是一個列表),如果不改變其中複雜元素,淺拷貝的值改變不會影響原來的值,但是改變原來的值的複雜子物件的值會影響淺拷貝的值

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]

解析:
如圖所示:

  1. 由於b是a的賦值,所以b的改變會導致a也改變
  2. c是a的淺拷貝,c[3]是一個可變物件,所以改變c[3]值會影響a的值
  3. d是a的深拷貝,d[3]的改變並不影響a的值