本文章純野生,無任何借鑑他人文章及抄襲等。堅持原創!!
前言
這是一個面試題。請簡述Python的淺拷貝和深拷貝?
看到別人的文章,都帶有畫圖的。雖說一圖千文,但靈魂畫手並不適合畫圖,所以這裏使用簡潔明瞭的句子去闡釋淺拷貝與深拷貝。
概念
淺拷貝和深拷貝
先說概念:
- 淺拷貝:只拷貝數據集合最外邊的一層,深層的數據只是做了內存地址引用,並沒有拷貝。
- 深拷貝:完全拷貝數據集合的所有數據,與源數據再無相關
可變對象和不可變對象
這裏還要說一個概念,就是Python的可變對象和不可變對象。
官方文檔釋義:
- 可變對象:可變對象可以在其 id() 保持固定的情況下改變其取值;
- 不可變對象:具有固定值的對象。不可變對象包括數字、字符串和元組。這樣的對象不能被改變。如果必須存儲一個不同的值,則必須創建新的對象。
- id(object): 函數用於獲取對象的內存地址,函數返回對象的唯一標識符,標識符是一個整數。
個人理解:
-
可變對象:通俗點講就是一個對象在修改它的值時候,不會改變該對象所指向的內存地址。
-
不可變對象:與可變對象相反。
-
淺拷貝:淺拷貝只是複製外圍的一層數據,內部的數據只是引用了原來的內存地址
-
深拷貝:對外圍和內部元素都進行了拷貝對象本身,而不是對象的引用
-
不可變類型數據沒有所謂的深淺拷貝,都是對源對象內存地址的引用、賦值也是對內存地址的引用。
Python常見的數據結構。
對象 | 可變對象 | 不可變對象 |
---|---|---|
整數int | √ | |
元組tuple | √ | |
字符串str | √ | |
浮點數float | √ | |
布爾值bool | √ | |
列表list | √ | |
集合set | √ | |
字典dict | √ |
建議移步Python官方中文文檔系統性的瞭解這幾個概念。
下面上例子,包懂!!!
代碼示例
== 與 is
Python的 == 是判斷兩個對象的值是否相等,is則是判斷兩個對象的內存地址是否相等。
來看下面一則例子。
>>>a = [1, 2, 3]
>>>b = [1, 2, 3] # 創建兩個a、b兩個列表
>>>a == b # 判斷a、b兩個對象的值是否相等
True
>>>a is b # 判斷a、b兩個對象的內存地址是否相等
False
>>>id(a),id(b) # 打印輸出兩個對象的內存地址,發現不一樣
(2692110484296, 2692110525256)
淺拷貝
- 只拷貝數據集合最外邊的一層,深層的數據只是做了內存地址引用,並沒有拷貝。
例如一個列表裏面嵌套了另一個列表:[1, 2, 3, [4, 5]]
>>>import copy # 導入模塊
>>>a = [1, 2, 3, [4, 5]]
>>>b = copy.copy(a) # 使用淺拷貝拷貝a對象
>>>b # 打印輸出b
[1, 2, 3, [4, 5]]
>>>id(a),id(b) # 打印輸出a、b的內存地址
(2692110485192, 2692110468616)
>>>a is b # a和b的內存地址不相等,所以返回False
False
>>>a[3] is idb[3] # 內層的b的[4,5]實際上是引用了a的[4,5]內存地址,即他們是相等的
True
>>>a[3][1] = 10 # 更改a的內層列表的第二個元素
>>>a # 打印輸出a
[1, 2, 3, [4, 10]]
>>>b # 打印輸出b,可以看到b也隨之更改了。
[1, 2, 3, [4, 10]]
相信看過上述的例子之後,你已經理解何爲淺拷貝了。
深拷貝
- 深拷貝:完全拷貝數據集合的所有數據,與源數據再無相關。
例如一個列表裏面嵌套了另一個列表:[1, 2, 3, [4, 5]]
>>>import copy # 導入模塊
>>>a = [1, 2, 3, [4, 5]]
>>>b = copy.deepcopy(a) # 使用深拷貝拷貝a對象
>>>id(a),id(b) # 打印輸出a、b的內存地址
(2692110512008, 2692110620872)
>>>a is b # 對象a、b內存地址不一樣,這裏爲False
False
>>>a[3] is b[3] # 對象內層地址也不一樣,這裏爲False
False
>>>a[3][1] = 10 # 更改a的內層列表的第二個元素
>>>a # 打印輸出a
[1, 2, 3, [4, 10]]
>>>b # 打印輸出b,可以看到b並沒有隨之改變
[1, 2, 3, [4, 5]]
相信看到這裏你已經能理解淺拷貝和深拷貝了。
文章寫的很菜,勿噴。
本意是用簡潔明瞭的話介紹一下淺拷貝和深拷貝,沒想到卻是很囉嗦。
不過囉嗦就歸囉嗦,當是做一個筆記吧。
後面的話
好了,本次的分享到此結束。
有任何疑問歡迎在下方留言哦。