python學習筆記–深拷貝與淺拷貝的區別

老男孩、小北發表於2018-12-03

首先我們來講講我們python中的可變物件和不可變物件:

可變物件:該物件指向記憶體中的值是可以改變的。實際上是其所指的值直接發生改變,而不是發生複製,或者開闢一個新的地址空間。例如:列表list,字典dict,集合set 
不可變物件:該物件所指向的記憶體中的值是不能被改變的。當改變一個變數時,由於其所指的值不能被改變,相當於把原來的值複製一份到新開闢的地址,再進行改變,並將變數指向這個新的地址空間。例如:數值型別(int、float)、字串str、元組tuple

python中物件的賦值實際上是物件的引用,例如:

a = [1,2,3]

實際上在電腦內部是生成一個地址將list[1,2,3]放在這個地址,在賦值給a時,就是講a指向了這個地址。如果此時我們再執行 a = [4,5,6],並不是說在我們的記憶體中[1,2,3]就不存在了,這個列表是一直存在的,只是我們將變數a指向了一個新的列表的地址。

  • 下面我們講講淺拷貝(包含可變物件:此處可變為中間的list物件):
 
  1. >>> alist=[1,2,3,["a","b"]]
  2. >>> b = alist
  3. >>>print b
  4. [1,2,3,[`a`,`b`]]
  5. >>> alist.append(5)
  6. >>>print alist
  7. [1,2,3,[`a`,`b`],5]
  8. >>>print b
  9. [1,2,3,[`a`,`b`],5]

在這個程式塊中,當我們執行alist.append(5)實際上改變的是alist這個變數指向的list,由於我們的變數b也是指向這個list,所以變數b的值也跟著改變。

  • copy.copy()淺拷貝 
    這個copy.copy沒有拷貝可變物件,即當可變物件發生變化時,所有的變數都會跟著發生變化。 
    例如:
 
  1. >>>import copy
  2. >>> c=copy.copy(alist)
  3. >>>print alist;print c
  4. [1,2,3,[`a`,`b`]]
  5. [1,2,3,[`a`,`b`]]
  6. >>> alist.append(5)
  7. >>>print alist;print c
  8. [1,2,3,[`a`,`b`],5]
  9. [1,2,3,[`a`,`b`]]
  10. >>> alist[3]
  11. [`a`,`b`]#這個物件是可變物件
  12. >>> alist[3].append(`cccc`)
  13. >>>print alist;print c
  14. [1,2,3,[`a`,`b`,`cccc`],5]
  15. [1,2,3,[`a`,`b`,`cccc`]]
  • copy.deepcopy拷貝了包含可變物件在內的所有物件
 
  1. >>>import copy
  2. >>> d=copy.deepcopy(alist)#此時dalist是兩個完全獨立的物件
  3. >>>print alist;print d
  4. [1,2,3,[`a`,`b`]]
  5. [1,2,3,[`a`,`b`]]始終沒有改變
  6. >>> alist.append(5)
  7. >>>print alist;print d
  8. [1,2,3,[`a`,`b`],5]
  9. [1,2,3,[`a`,`b`]]始終沒有改變
  10. >>> alist[3]
  11. [`a`,`b`]
  12. >>> alist[3].append("ccccc")
  13. >>>print alist;print d
  14. [1,2,3,[`a`,`b`,`ccccc`],5]
  15. [1,2,3,[`a`,`b`]]始終沒有改變

相關文章