python之淺拷貝與深拷貝
- 2020 年 1 月 9 日
- 筆記
1. 淺拷貝
淺拷貝是對於一個對象的頂層拷貝 通俗的理解是:拷貝了引用,並沒有拷貝內容
In [10]: a = [11,22,33] In [11]: b = a In [12]: id(a) Out[12]: 140343572333832 In [13]: id(b) Out[13]: 140343572333832 In [14]: a[0] = 'aa' In [15]: a Out[15]: ['aa', 22, 33] In [16]: b Out[16]: ['aa', 22, 33]
當b = a時,實際上是將a列表的記憶體地址賦值給了b,那麼變數a與變數b指向的是同一記憶體地址!
2. 深拷貝
深拷貝是對於一個對象所有層次的拷貝(遞歸)
In [17]: import copy In [18]: c = copy.deepcopy(a) In [19]: id(a) Out[19]: 140343572333832 In [20]: id(c) Out[20]: 140343572336840 In [21]: a Out[21]: ['aa', 22, 33] In [22]: c Out[22]: ['aa', 22, 33] In [23]: a[0] = 11 In [24]: a Out[24]: [11, 22, 33] In [25]: c Out[25]: ['aa', 22, 33]
深拷貝不僅拷貝引用還拷貝值,所以記憶體地址不一樣!
再看下面的程式碼,進一步理解淺拷貝與深拷貝:
注意:變數e由於用的是深拷貝,所以引用與值都是獨立的一份
copy.copy
上面演示了copy.deepcopy的用法,下面看copy.copy的用法:
In [40]: a = [1,2,3] In [41]: b = [4,5,6] In [42]: c = [a,b] In [43]: e = copy.copy(c) In [44]: a.append(4) In [45]: c[0] Out[45]: [1, 2, 3, 4] In [46]: id(c) Out[46]: 140343572344200 In [47]: id(e) Out[47]: 140343588052232
圖解:
由於變數e用的是copy.copy(c)的方法,所以只拷貝了列表[a,b]的引用(copy.copy只能拷貝第一層引用),所以變數c與變數e的記憶體地址是不同的,但當改變[a,b]列表中a列表的值時,發現e變數中的a列表也會改變,說明copy.copy方法只拷貝了列表[a,b]列表的引用,而沒有拷貝列表[a,b]中列表a與列表b的引用。實際上列表[a,b]中的兩個列表a,b的記憶體地址還是指向的a與b
copy元組時的特點
copy.copy方法在copy時會自動判斷copy的對象是可變類型還是不可變類型,如果是不可變類型,那麼直接將引用指向copy的對象,如果是可變類型,那麼只拷貝第一層的引用,後面的引用不會拷貝