Python學習筆記(九)—Python中的賦值、淺拷貝和深拷貝(含圖)

轉載請注明出處:http://www.lxweimin.com/p/db57f7f70a5c
本文出自Shawpoo的簡書
我的博客:CSDN博客

【Python學習筆記專欄】:http://blog.csdn.net/column/details/17658.html

在學習Python的過程中,經常會對變量進行“賦值”,有時候又要對變量的值做臨時處理,而又不能改變原來變量的值,這就可能用到了“淺拷貝”和“深拷貝”。所以下面通過具體的例子來區分它們三者的不同。

另外,大多數面向對象的語言都會涉及到變量的“賦值”、“淺拷貝”和“深拷貝”,如Python,Java或者C++等。

一、賦值

在Python中,賦值很簡單,例如,將一個變量的值賦值給另一個變量,其實就是將這兩個變量指向同一個內存地址。所以如果這個變量的值改變了,那么另一個變量的值也會跟著改變,因為它們的內存地址始終相同。例:

a = [1, 2, 3, ['a', 'b', 'c']]
b = a
print(id(a), id(b)) #打印它們各自的內存地址
print(a)
print(b)
a.append(4)
print("-----------")
print(id(a), id(b))
print(a)
print(b)
a[3].append('d')
print("-----------")
print(id(a), id(b))
print(a)
print(b)
print(a is b)

執行結果:
2524323181384 2524323181384
[1, 2, 3, ['a', 'b', 'c']]
[1, 2, 3, ['a', 'b', 'c']]
-----------
2524323181384 2524323181384
[1, 2, 3, ['a', 'b', 'c'], 4]
[1, 2, 3, ['a', 'b', 'c'], 4]
-----------
2524323181384 2524323181384
[1, 2, 3, ['a', 'b', 'c', 'd'], 4]
[1, 2, 3, ['a', 'b', 'c', 'd'], 4]
True

通過上述的例子可以看出,在“賦值”的情況下,變量b的值始終隨著變量a的值改變而改變,也就是內存地址始終相同。

圖解: b = a: 賦值引用,a 和 b 都指向同一個對象。

直接賦值

二、淺拷貝

淺拷貝,只拷貝父對象,不會拷貝父對象中的子對象。如果該對象沒有子對象的話,其淺拷貝和賦值的結果是一樣的。淺拷貝可以通過導入copy模塊中的copy()方法來完成,或者調用對象本身的copy()方法。例:

import copy # 導入copy模塊
a = [1, 2, 3, ['a', 'b', 'c']]
b = copy.copy(a)   # a.copy()
print(id(a), id(b))
print(a is b)
print(a)
print(b)
a.append(4)
print("-----------")
print(id(a), id(b))
print(a)
print(b)
a[3].append('d')
print("-----------")
print(id(a), id(b))
print(a)
print(b)
print(a is b)
print(a[3] is b[3])

運行結果:
1558199464776 1558199464904
False
[1, 2, 3, ['a', 'b', 'c']]
[1, 2, 3, ['a', 'b', 'c']]
-----------
1558199464776 1558199464904
[1, 2, 3, ['a', 'b', 'c'], 4]
[1, 2, 3, ['a', 'b', 'c']]
-----------
1558199464776 1558199464904
[1, 2, 3, ['a', 'b', 'c', 'd'], 4]
[1, 2, 3, ['a', 'b', 'c', 'd']]
False
True

通過上述的例子可以看出,我們改變變量a中父對象的值,不會影響變量b,但是改變變量a中子對象的值,那么變量b也會隨之改變,這就是淺拷貝,只拷貝父對象,而不拷貝子對象。

圖解:b = copy.copy(a): 淺拷貝, a 和 b 是一個獨立的對象,但它們的子對象還是指向同一對象(內存地址)。

淺拷貝

三、深拷貝

深拷貝,也就是完全拷貝,包括拷貝對象的父對象及其子對象。拷貝后是
兩個完全獨立的對象,互不影響。我們可以通過copy模塊中的deepcopy()方法來完成。

import copy

a = [1, 2, 3, ['a', 'b', 'c']]
b = copy.deepcopy(a)
print(id(a), id(b))
print(a is b)
print(a)
print(b)
a.append(4)
print("-----------")
print(id(a), id(b))
print(a)
print(b)
a[3].append('d')
print("-----------")
print(id(a), id(b))
print(a)
print(b)
print(a is b)
print(a[3] is b[3])

執行結果:
3143729499336 3143729558024
False
[1, 2, 3, ['a', 'b', 'c']]
[1, 2, 3, ['a', 'b', 'c']]
-----------
3143729499336 3143729558024
[1, 2, 3, ['a', 'b', 'c'], 4]
[1, 2, 3, ['a', 'b', 'c']]
-----------
3143729499336 3143729558024
[1, 2, 3, ['a', 'b', 'c', 'd'], 4]
[1, 2, 3, ['a', 'b', 'c']]
False
False

通過上述的例子可以看出,不管我們改變變量a中父對象的值,還是改變子對象的值,都不會影響變量b的值,那么說明此時變量a和變量b已經完全獨立,這就是深拷貝,拷貝父對象及其子對象。

圖解: b = copy.deepcopy(a): 深拷貝, a 和 b 完全拷貝了父對象及其子對象,兩者是完全獨立的。

深拷貝

總結

  • 賦值:其實就是對象地址的引用。
  • 淺拷貝(copy):調用copy模塊的copy()方法,只拷貝父對象,不會拷貝對象內部的子對象。
  • 深拷貝(deepcopy): 調用copy模塊的deepcopy()方法,完全拷貝了父對象及其子對象。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 摘自: http://www.cocoachina.com/ios/20150803/12872.html 說明...
    program袁閱讀 885評論 1 3
  • 昨天父親節,整個朋友圈都在刷屏祝福天下父親節日快樂。我想到了我那不善言談的父親。 從小到大,只有媽媽陪伴著長大,我...
    言小胡閱讀 154評論 0 1
  • 周末無事,與朋友閑逛。本來想找茶馬古道,怎奈山間防火形式緊張,攔下不讓過。只好返出來,路越來越窄,盤山下來,看見一...
    天蟬女閱讀 312評論 0 1
  • 圖文無關 一、家大家小夠住就好,只要有心愛的人做伴,哪怕陋室又何防?關鍵是白天醒的開心,晚上睡的舒心。 二、男人什...
    身心驛站閱讀 514評論 0 0