python怎麼淺拷貝和深拷貝?首先,我們知道Python3中,有6個标準的數據類型,他們又分為可變和不可變,我來為大家講解一下關于python怎麼淺拷貝和深拷貝?跟着小編一起來看一看吧!
首先,我們知道Python3中,有6個标準的數據類型,他們又分為可變和不可變。
不可變數據(3個):
可變數據(3個):
import copy
# 不可變類型 Number String Tuple
print("對于不可 變類型 Number String Tuple,淺複制僅僅是地址指向,不會開辟新空間拷貝值")
num1 = 17
num2 = copy.copy(num1)
print("num1:" str(id(num1)))
print("num2:" str(id(num1)))
# num1和num2的地址都相同
str1 = "hello"
str2 = copy.copy(str1)
print("str1:" str(id(str1)))
print("str2:" str(id(str2)))
# str1和str2的地址都相同
tup1 = (18, "tom")
tup2 = copy.copy(tup1)
print("tup1:" str(id(tup1)))
print("tup2:" str(id(tup2)))
# tup1和tup2的地址都相同
print("="*20)
print("對于可變類型 List、Dictionary、Set,淺複制會開辟新的空間地址(僅僅是最頂層開辟了新的空間),進行淺拷貝")
list1 = [11,12]
list2 = copy.copy(list1)
print("list1:" str(id(list1)))
print("list2:" str(id(list2)))
# list1和list2的地址不相同
dic1 = [11,12,"hi"]
dic2 = copy.copy(dic1)
print("dic1:" str(id(dic1)))
print("dic2:" str(id(dic2)))
# dic1和dic2的地址不相同
set1 = {"AA","BB"}
set2 = copy.copy(set1)
print("set1:" str(id(set1)))
print("set2:" str(id(set2)))
# set1和set2的地址不相同
結果:
對于不可 變類型 Number String Tuple,淺複制僅僅是地址指向,不會開辟新空間拷貝值
num1:4449693616
num2:4449693616
str1:4452098488
str2:4452098488
tup1:4451942472
tup2:4451942472
====================
對于可變類型 List、Dictionary、Set,淺複制會開辟新的空間地址,進行淺拷貝
list1:4456844424
list2:4452360136
dic1:4452358856
dic2:4456844744
set1:4452279016
set2:4452279464
import copy
l1 = [11, 12]
l2 = [21, 22]
num = 555
allOne = [l1, l2,num]
# 淺拷貝,創建出一個對象,并把舊對象元素的 引用地址 拷貝到新對象當中。
# 也就是說,兩個對象裡面的元素通過淺拷貝指向的還是同一個地址
allOne2 = copy.copy(allOne)
l1[0] = 16 # 此處修改,會使得 allOne 和 allOne2的第0個元素的值都發生改變,因為l1是List,是可變對象
allOne[2] = 666 # 此處修改,隻會allOne的num的值,因為不可變對象一旦重新複制,地址就會發生改變。(不可變嘛)
num = 777 # 此處不會改變 allOne 和 allOne2的值,因為相當于 777 複制給一個全新的地址,這個num跟其他num已經沒關系了
print(allOne)
print(allOne2)
print("id allOne:" str(id(allOne)))
print("id allOne[0]:" str(id(allOne[0])))
print("id allOne[1]:" str(id(allOne[1])))
print("id allOne[2]:" str(id(allOne[2])))
print("===")
print("id allOne2:" str(id(allOne2)))
print("id allOne2[0]:" str(id(allOne2[0])))
print("id allOne2[1]:" str(id(allOne2[1])))
print("id allOne2[2]:" str(id(allOne2[2])))
結果:
[[16, 12], [21, 22], 666]
[[16, 12], [21, 22], 555]
id allOne:4467341640
id allOne[0]:4471819912
id allOne[1]:4467342920
id allOne[2]:4466847696
===
id allOne2:4471820232
id allOne2[0]:4471819912
id allOne2[1]:4467342920
id allOne2[2]:4466081744
結論:
備注:List是可變類型
對于不可變類型被修改後造成的影響,我們用一個更加簡單的例子便可更好理解:
num = 123
print(str(id(num)))
num = 666
print(str(id(num)))
結果:
4348603632
4350009296
我們對3種可變類型3種不可變類型進行深拷貝。
結果發現,和淺拷貝幾乎一緻。
其實這也好理解,因為的深拷貝對比淺拷貝,強調的是 遞歸,強調的是資源素。
對了頂層的操作,深淺拷貝無異。
import copy
# 不可變類型 Number String Tuple
print("對于不可 變類型 Number String Tuple,深複制依然是地址指向,不會開辟新空間拷貝值")
num1 = 17
num2 = copy.deepcopy(num1) # 深拷貝
print("num1:" str(id(num1)))
print("num2:" str(id(num1)))
# num1和num2的地址都相同
str1 = "hello"
str2 = copy.deepcopy(str1) # 深拷貝
print("str1:" str(id(str1)))
print("str2:" str(id(str2)))
# str1和str2的地址都相同
tup1 = (18, "tom")
tup2 = copy.deepcopy(tup1) # 深拷貝
print("tup1:" str(id(tup1)))
print("tup2:" str(id(tup2)))
# tup1和tup2的地址都相同
print("="*20)
print("對于可變類型 List、Dictionary、Set,深拷貝會開辟新的空間地址,進行拷貝")
list1 = [11,12]
list2 = copy.deepcopy(list1) # 深拷貝
print("list1:" str(id(list1)))
print("list2:" str(id(list2)))
# list1和list2的地址不相同
dic1 = [11,12,"hi"]
dic2 = copy.deepcopy(dic1) # 深拷貝
print("dic1:" str(id(dic1)))
print("dic2:" str(id(dic2)))
# dic1和dic2的地址不相同
set1 = {"AA","BB"}
set2 = copy.deepcopy(set1) # 深拷貝
print("set1:" str(id(set1)))
print("set2:" str(id(set2)))
# set1和set2的地址不相同
import copy
l1 = [11, 12]
l2 = [21, 22]
num = 555
allOne = [l1, l2,num]
# 淺拷貝,除了頂層拷貝,還對子元素也進行了拷貝(本質上遞歸淺拷貝)
# 經過深拷貝後,原始對象和拷貝對象所有的元素地址都沒有相同的了
allOne2 = copy.deepcopy(allOne) # copy.deepcopy 深拷貝
allOne[1] = [113,114]
allOne2[2] = [227,228]
print(allOne)
print(allOne2)
print("id allOne:" str(id(allOne)))
print("id allOne[0]:" str(id(allOne[0])))
print("id allOne[1]:" str(id(allOne[1])))
print("id allOne[2]:" str(id(allOne[2])))
print("===")
print("id allOne2:" str(id(allOne2)))
print("id allOne2[0]:" str(id(allOne2[0])))
print("id allOne2[1]:" str(id(allOne2[1])))
print("id allOne2[2]:" str(id(allOne2[2])))
結果:
[[11, 12], [113, 114], 555]
[[11, 12], [21, 22], [227, 228]]
id allOne:4549589640
id allOne[0]:4554067720
id allOne[1]:4554067848
id allOne[2]:4548329424
===
id allOne2:4554067912
id allOne2[0]:4554067784
id allOne2[1]:4554067592
id allOne2[2]:4554100808
除了copy模塊的中的copy和deepcopy,還有其他自帶的方式可實現拷貝。
l1 = [11, 12]
l2 = [21, 22]
num = 555
orgi = [l1, l2, num]
nList = orgi[:]
print("orgi:" str(id(orgi)))
print("orgi[0]:" str(id(orgi[0])))
print("orgi[1]:" str(id(orgi[1])))
print("orgi[2]:" str(id(orgi[2])))
print("*"*30)
print("nList:" str(id(nList)))
print("nList[0]:" str(id(nList[0])))
print("nList[1]:" str(id(nList[1])))
print("nList[2]:" str(id(nList[2])))
用分片表達式進行的拷貝,是淺拷貝。
dic = {"key": "hello", "num": 18}
dic2 = dic.copy()
dic["key"] = "one"
dic2["key"] = "two"
print(dic)
print("dic:" str(id(dic)))
print(dic2)
print("dic2:" str(id(dic2)))
結果:
{'key': 'one', 'num': 18}
dic:4382946792
{'key': 'two', 'num': 18}
dic2:4382946864
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!