Python中淺拷貝和深拷貝的了解與研究
單層淺拷貝
import copy
a = 1 # 不可變資料類型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 記憶體位址相同
a = [1,2] # 可變資料類型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 記憶體位址不相同
單層深拷貝
import copy
a = 1 # 不可變資料類型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a)) # 記憶體位址相同
a = [1,2] # 可變資料類型
copy_a = copy.deepcopy(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)) # 記憶體位址相同
# 情況二,内嵌不可變資料類型
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)) # 不可變資料類型
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])) # 記憶體位址相同
結論二:
淺拷貝:深拷貝:
- 外層是不可變類型、不管内層是否可變都是引用拷貝
- 外層是可變類型,不管内層是否可變都會從新建立新的記憶體空間
- 外層是不可變類型,會遞歸判斷内層資料類型、如果可變則建立新的記憶體位址、都為不可變就是引用拷貝
- 外層是可變資料類型、不管内層是否可變都會創新新的記憶體位址、但是内部如果為可變則遞歸建立、不可變則為引用位址
總結:
- 淺拷貝隻做最頂層的資料類型判斷
- 如果頂層是可變類型則建立新的記憶體空間
- 如果頂層是不可變資料類型就是引用拷貝
原文位址 https://www.cnblogs.com/fandx/p/10462913.html
- 深拷貝做遞歸拷貝,可以遞歸拷貝所有的内部嵌套資料(可以了解為循環周遊做淺拷貝判斷)
- 深拷貝遞歸拷貝遇到可變類型則建立新的記憶體空間
- 深拷貝遞歸拷貝遇到不可變資料類型就是拷貝的引用