《Python面試每日一題》之深拷貝、淺拷貝

問題描述:

深拷貝和淺拷貝的區別是什麼?

答:

深拷貝是將對象內容複製給另一個對象,在內存中再開闢一段新的空間。這意味着如果對對象的副本進行更改時不會影響原對象。使用copy模塊的deepcopy函數可以深拷貝一個對象(詳見實例代碼2)。
當對象是非嵌套類型時,淺拷貝是將對象的引用複製給另一個對象,在內存中不開闢新的空間。因此,如果我們在副本中進行更改,則會影響原對象。例如:列表賦值、列表的切片等。使用copy模塊的copy函數可以淺拷貝一個對象。
當對象是嵌套類型,且最頂層非元組類型時,淺拷貝該對象只在內存內開闢一段新的空間給最頂層,而對於非頂層的數據只是引用指向(詳見實例代碼1)

a = ["tomato1998","1998tomato","toma1998to"]
b = a
print("a的初始內容:",a)
print("b的初始內容:",b)
a.append("to1998mato")
print("a修改後a的內容:",a)
print("a修改後b的內容:",b)
print(id(a))
print(id(b))

運行結果是:

a的初始內容: ['tomato1998', '1998tomato', 'toma1998to']
b的初始內容: ['tomato1998', '1998tomato', 'toma1998to']
a修改後a的內容: ['tomato1998', '1998tomato', 'toma1998to', 'to1998mato']
a修改後b的內容: ['tomato1998', '1998tomato', 'toma1998to', 'to1998mato']
1672231092296
1672231092296

使用copy模塊的deepcopy函數可以深拷貝一個對象,我們將上述代碼修改爲深拷貝。

import copy
a = ["tomato1998","1998tomato","toma1998to"]
b = copy.deepcopy(a)
print("a的初始內容:",a)
print("b的初始內容:",b)
a.append("to1998mato")
print("a修改後a的內容:",a)
print("a修改後b的內容:",b)
print(id(a))
print(id(b))

運行結果是:

a的初始內容: ['tomato1998', '1998tomato', 'toma1998to']
b的初始內容: ['tomato1998', '1998tomato', 'toma1998to']
a修改後a的內容: ['tomato1998', '1998tomato', 'toma1998to', 'to1998mato']
a修改後b的內容: ['tomato1998', '1998tomato', 'toma1998to']
2350861606664
2350861605640

需要注意的是,如果拷貝的對象是不可變類型(例如元組),那麼無法對其進行深拷貝和淺拷貝,僅僅是指向。(詳見實例代碼3)
如果用copy或deepcopy對一個全部都是不可變類型的數據進行拷貝,那麼此時僅僅是引用指向,無深拷貝和淺拷貝之說。
如果拷貝的是一個擁有不可變類型的數據,即使最頂層是元組類型,那麼deepcopy依然是深拷貝,而copy還是引用指向。


實例代碼1:

"""對嵌套類型對象淺拷貝"""
import copy
a = ["tomato2020",("tomato1988","tomato1998"),[11,22,33]]
b = copy.copy(a)
print("a的內存空間是:",id(a))
print("b的內存空間是:",id(b))
print("a的第一個元素內存空間是:",id(a[0]))
print("b的第一個元素內存空間是:",id(b[0]))
print("a的第二個元素內存空間是:",id(a[1]))
print("b的第二個元素內存空間是:",id(b[1]))
print("a的第三個元素內存空間是:",id(a[2]))
print("b的第三個元素內存空間是:",id(b[2]))

運行結果:

a的內存空間是: 2524633652488
b的內存空間是: 2524633718344
a的第一個元素內存空間是: 2524633623344
b的第一個元素內存空間是: 2524633623344
a的第二個元素內存空間是: 2524630539912
b的第二個元素內存空間是: 2524630539912
a的第三個元素內存空間是: 2524633657736
b的第三個元素內存空間是: 2524633657736

實例代碼2

"""對嵌套類型對象深拷貝"""
a = ["tomato2020",("tomato1988","tomato1998"),[11,22,33]]
b = copy.deepcopy(a)
print("a的內存空間是:",id(a))
print("b的內存空間是:",id(b))
print("a的第一個元素內存空間是:",id(a[0]))
print("b的第一個元素內存空間是:",id(b[0]))
print("a的第二個元素內存空間是:",id(a[1]))
print("b的第二個元素內存空間是:",id(b[1]))
print("a的第三個元素內存空間是:",id(a[2]))
print("b的第三個元素內存空間是:",id(b[2]))

運行結果:

a的內存空間是: 3132883426568
b的內存空間是: 3132883492296
a的第一個元素內存空間是: 3132883397232
b的第一個元素內存空間是: 3132883397232
a的第二個元素內存空間是: 3132880313928
b的第二個元素內存空間是: 3132880313928
a的第三個元素內存空間是: 3132883431752
b的第三個元素內存空間是: 3132883492360

實例代碼3:

"""對不可變類型數據深拷貝、淺拷貝"""
a = ("tomato1998","tomato2020",11)
b = copy.copy(a)
c = copy.deepcopy(a)
print("a的內存空間是:",id(a))
print("b的內存空間是:",id(b))
print("c的內存空間是:",id(c))

運行結果:

a的內存空間是: 1201743173240
b的內存空間是: 1201743173240
c的內存空間是: 1201743173240
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章