關於python中的深拷貝和淺拷貝的總結

2021-10-06 17:32:47 字數 3692 閱讀 8722

了解深拷貝和淺拷貝之前你得先知道什麼時可變物件什麼是不可變物件傳送門

深拷貝和淺拷貝拷貝不可變物件時

import copy

a = 1

b = copy.copy(a)

c = copy.deepcopy(a)

print(id(a))

print(id(b))

print(id(c)

輸出結果

140714631783056

140714631783056

140714631783056

當深拷貝和淺拷貝拷貝可變物件時
a = [1,2]

b = copy.copy(a)

c = copy.deepcopy(a)

print(a)

print(b)

print(c)

print(id(a))

print(id(b))

print(id(c))

輸出結果:

[1, 2, 3]

[1, 2]

[1, 2]

2161196250376

2161196250248

2161196250632

不管深拷貝還是淺拷貝對不可變資料型別都是引用記憶體位址

不管深拷貝還是淺拷貝對可變資料型別都是會重新建立新的記憶體空間

# -----------不可變資料型別---------

# 情況一,內嵌可變資料型別

import copy

a = ([1,2],(3,4)) # 不可變資料型別

copy_a = copy.copy(a)

print(id(a),id(copy_a)) # 記憶體位址相同

# 情況二,內嵌不可變資料型別

a = ((1,2),(3,4)) # 不可變資料型別

copy_a = copy.copy(a)

print(id(a),id(copy_a)) # 記憶體位址相同

#-----------可變資料型別-------------

# 情況一,內嵌可變資料型別

import copy

a = [(1,2),[3,4]] # 可變資料型別

copy_a = copy.copy(a)

print(id(a),id(copy_a)) # 記憶體位址不相同

# 情況一, 可變資料型別 內嵌可變資料型別

import copy

a = [(1,2),(3,4)] # 可變資料型別

copy_a = copy.copy(a)

print(id(a),id(copy_a)) # 記憶體位址不相同

import copy

a = [1,2,[3,4]]

b = copy.copy(a)

print(a)

print(b)

print(id(a))

print(id(b))

print(a)

print(b)

print(id(a))

print(id(b))

輸出結果:

[1, 2, [3, 4]]

[1, 2, [3, 4]]

2879593821128

2879593821512

[1, 2, [3, 4, 5]]

[1, 2, [3, 4, 5]]

2879593821128

2879593821512 # 記憶體位址雖然不一樣,但是當a的頂層的資料發生了變化 b的頂層的資料也發生了變化

# -----------不可變資料型別---------

# 情況一,內嵌可變資料型別

import copy

a = ([1,2],(3,4)) # 不可變資料型別

copy_a = copy.deepcopy(a)

print(id(a),id(copy_a)) # 記憶體位址不相同

# 情況二,內嵌不可變資料型別

a = ((1,2),(3,4)) # 不可變資料型別

copy_a = copy.deepcopy(a)

print(id(a),id(copy_a)) # 記憶體位址相同

#-----------可變資料型別-------------

# 情況一,內嵌可變資料型別

import copy

a = [(1,2),[3,4]] # 可變資料型別

copy_a = copy.deepcopy(a)

print(id(a),id(copy_a)) # 記憶體位址不相同

print(id(a[0]),id(copy_a[0])) # 記憶體位址相同

print(id(a[1]),id(copy_a[1])) # 記憶體位址不相同

# 情況一, 可變資料型別 內嵌可變資料型別

import copy

a = [(1,2),(3,4)] # 可變資料型別

copy_a = copy.deepcopy(a)

print(id(a),id(copy_a)) # 記憶體位址不相同

print(id(a[0]),id(copy_a[0])) # 記憶體位址相同

a = [1,2,[3,4]]

b = copy.deepcopy(a)

print(a)

print(b)

print(id(a))

print(id(b))

print(a)

print(b)

print(id(a))

print(id(b))

輸出結果:

[1, 2, [3, 4]]

[1, 2, [3, 4]]

2049726264200

2049726264584

[1, 2, [3, 4, 5]]

[1, 2, [3, 4]]

2049726264200 # 這時候和淺拷貝不一樣了哦,雖然a的頂層的資料發生了變化,但是b還是未發生變化

2049726264584

淺拷貝:

外層是不可變型別、不管內層是否可變都是引用拷貝

外層是可變型別,不管內層是否可變都會從新建立新的記憶體空間

當拷貝另乙個物件後,頂層的資料時引用原物件的,所以原物件的頂層資料發生改變,拷貝的也會發生改變

深拷貝:

外層是不可變型別,會遞迴判斷內層資料型別、如果可變則建立新的記憶體位址、都為不可變就是引用拷貝

外層是可變資料型別、不管內層是否可變都會創新新的記憶體位址、但是內部如果為可變則遞迴建立、不可變則為引用位址

面對可變物件的時候就相當於時將a完全拷貝到乙個新的記憶體位址

淺拷貝只做最頂層的資料型別判斷

如果頂層是可變型別則建立新的記憶體空間

如果頂層是不可變資料型別就是引用拷貝

拷貝做遞迴拷貝,可以遞迴拷貝所有的內部巢狀資料(可以理解為迴圈遍歷做淺拷貝判斷)

深拷貝遞迴拷貝遇到可變型別則建立新的記憶體空間

深拷貝遞迴拷貝遇到不可變資料型別就是拷貝的引用

參考部落格:

關於python的深拷貝和淺拷貝

寫類函式的時候出了乙個錯,原 寫在這裡 def update self,wm,vm,ts,pos,vn,att 上一時刻位置,速度 pos pre pos self.pos pos vn pre vn self.vn vn vn更新 self.vn self.vn self.delta vn pos...

python中的淺拷貝和深拷貝

不得不說 python核心程式設計 是一本好書,看到其中一節做一下隨筆。在python中,當建立乙個物件後,然後把它賦給另乙個物件時,python並沒有去拷貝這個物件,而是拷貝了這個物件的引用。看不懂沒關係,我們看乙個例子。raw list first second 12 32 copy list ...

python中的深拷貝和淺拷貝

淺拷貝 copy 不拷貝物件的內容,僅僅拷貝子物件的引用 深拷貝 deepcopy 會連同拷貝子物件的記憶體,對子物件的修改不會影響源物件 下面用 來測試 import copy deftest copy 淺拷貝測試 a 10 20,5,6 b copy.copy a print a a,end t...