深入理解Python中賦值、深拷貝(deepcopy)、淺拷貝(copy)


賦值

python跟java中的變量本質是不一樣的,Python的變量實質上是一個指針(int型或str型),而java的變量是一個可操作的存儲空間。

a = 123
b = a

print(id(a))
print(id(b))

print(a is b)


result:

  26848576
  26848576
  True

這里可以看到a和b的地址是一樣的,a=123,實質上是將a這個對象"貼到"123上;同樣,b=a,也是將b這個對象“貼到”123上,這里變量實際上是個“便利貼“。

下面用一個可變的對象list來做說明:

a = [1, 2, 3] b = a a.append(4) a[0] = 6
print(a) print(b) result: [6, 2, 3, 4] [6, 2, 3, 4]

首先把a和b貼在 [1,2,3]這個對象上,然后通過append,[1,2,3]這個對象變成了[1,2,3,4],再通過a[0]=6,將對象[1,2,3,4]的第0個元素地址對應值改為6,

則最終這個對象是[6,2,3,4],然而a和b仍然是貼在這個對象上的,即a和b都是[6,2,3,4]

 

 

淺拷貝(copy)

對於淺拷貝有兩種情況:

1. 淺拷貝值是不可變對象(數值,字符串,元組)時,等同於賦值,對象的id值與淺拷貝原來的值相同。

 

import copy a = 1 b = a c = copy.copy(a) print(id(a)) print(id(b)) print(id(c)) result: 35258712
35258712
35258712

 

 

 

2. 淺拷貝值是可變對象(list,dict)時:

 2.1 不包含子對象

# coding:utf-8
import copy a = [1, 2, 3] b = a c = copy.copy(a) print("append前c={}".format(id(c))) a.append(4) print("a={}".format(id(a))) print("b={}".format(id(b))) print("append后c={}".format(id(c))) print("a值={}".format(a)) print("b值={}".format(b)) print("c值={}".format(c)) result: append前c=139982846485352 a=139982846912272 b=139982846912272 append后c=139982846485352 a值=[1, 2, 3, 4] b值=[1, 2, 3, 4] c值=[1, 2, 3]

對於不包含子對象的情況下,原值的改變並不會影響淺拷貝的值,同時淺復制的值改變也並不會影響原值,並且淺拷貝是新開辟的一塊內存,與原對象內存地址不同。

 

 2.2 包含子對象

# coding:utf-8
import copy a = [1, [4], 2, 3] b = a c = copy.copy(a) print("append前c={}".format(id(c))) a.append(5) a[1].append(9) print("a={}".format(id(a))) print("b={}".format(id(b))) print("append后c={}".format(id(c))) print("a值={}".format(a)) print("b值={}".format(b)) print("c值={}".format(c)) result: append前c=140519703466856 a=140519703889752 b=140519703889752 append后c=140519703466856 a值=[1, [4, 9], 2, 3, 5] b值=[1, [4, 9], 2, 3, 5] c值=[1, [4, 9], 2, 3]

 可以看出,淺拷貝只拷貝父對象([1,2,3]),不會拷貝對象內部的子對象([4]),改變原對象中復雜子對象的值時會改變淺拷貝的值。

 

 

深拷貝(deepcopy)

 

# coding:utf-8
import copy a = [1, [4], 2, 3] print("a原始值={}".format(a)) b = a d = copy.deepcopy(a) a.append(5) a[1].append(9) print("a={}".format(id(a))) print("b={}".format(id(b))) print("d={}".format(id(d))) print("a值={}".format(a)) print("b值={}".format(b)) print("d值={}".format(d)) result: a原始值=[1, [4], 2, 3] a=139675956164440 b=139675956164440 d=139675955741904 a值=[1, [4, 9], 2, 3, 5] b值=[1, [4, 9], 2, 3, 5] d值=[1, [4], 2, 3]

 

深拷貝則會拷貝對象及其子對象,深拷貝的時候會將復雜對象的每一層復制一個單獨的個體出來,原對象的值改變時並不會影響deepcopy的值,

但是,由於深拷貝需要維護一個 內存 用於記錄已經拷貝的對象,所以深拷貝的速度會比較慢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM