深淺copy詳解

深淺copy

前言:深淺copy會在很多面試題中都會問到,所以搞懂它們之間的區別是很有必要性的

本篇中的所有圖解只是幫助大家進行理解

1. 可變與不可變數據類型

  • 可變數據類型:列表,字典,集合
  • 不可變數據類型:字符串,元組,數字

2. 淺拷貝
先拿圖說話:圖中的123123等數值假設爲內存地址
在這裏插入圖片描述
在圖中我們可以明顯的看到淺拷貝過後,兩個列表l1和l2的引用還是指的是同一個值,所以當我們更改這兩個列表的任何可變數據類型時,另一個列表的值一定會跟着變化。

注意:這裏我強調了更改的值必須是可變數據類型時,另一個列表的值纔會跟着變化

代碼證明:

  1. 更改嵌套列表的值
    l1 = [1, '小明', [1, '小紅', 3]]
    l2 = l1.copy()   # 或者導入copy模塊,l2 = copy.copy(l1)
    
    l1[-1][1] = '李華'
    print(id(l1))
    print(id(l2))
    
    print(id(l1[-1]))
    print(id(l2[-1]))
    print(l1)
    print(l2)
    
    # 輸出:
    	400648025856   # 兩個列表的內存地址不同代表另外給l2開闢一塊新的空間	
    	400648025984
    	
    	117588479680    # 證明兩個列表中的可變數據類型爲同一個
    	117588479680
    	[1, '小明', [1, '李華', 3]]   # 對l1的嵌套列表進行了更改,l2也跟着變化,代表了兩個列表引用的值是同一個
    	[1, '小明', [1, '李華', 3]]
    
  2. 更改列表中不可變數據類型的值
    l1 = [1, '小明', [1, '小紅', 3]]
    l2 = l1.copy()
    
    l1[1] = '小張'
    print(l1)
    print(l2)
    
    輸出:
    	[1, '小張', [1, '小紅', 3]]  # 兩個列表的值竟然不一樣了
    	[1, '小明', [1, '小紅', 3]]
    
    這時肯定就有人疑惑了,不是說兩個列表都是引用的同一個值麼,爲什麼l1的值更改了,而l2的值沒有更改呢?原因是這樣的,我們其實更改的值不是真實存儲的值,而且更改了l1列表中內存地址爲456456的引用,將456456指向了另一個值 ‘小張’,主要原因就是字符串它是不可變的數據類型,所以我們更改不了字符串的值。
    在這裏插入圖片描述
    總結:根據以上實驗,我們可以這樣理解,淺拷貝就是兩個列表中的可變數據類型仍是同一個。更改任何一個列表中的可變數據,另一個列表的值也會跟着變化

3. 深拷貝
和字面意思一樣,完全複製一份新的出來,與原列表再無任何聯繫。這裏就不再畫圖。

我們首先得藉助內置的copy模塊

  1. 更改嵌套的可變數據類型,這裏我們以字典進行演練。注意與列表一樣也是可變數據類型。

    import copy
    l1 = [1, '小明', {'name': '小張'}]
    l2 = copy.deepcopy(l1)
    
    l1[-1]['name'] = '小花'
    print(id(l1))
    print(id(l2))
    print(l1)
    print(l2)
    
    # 輸出:
    	705449836608   # 兩個列表的內存地址仍不一樣,代表爲拷貝的l2新開闢了一塊空間
    	705449810432
    	[1, '小明', {'name': '小花'}]   # 更改了l1中的可變數據類型字典的值,l1變化了,而l2沒有變化
    	[1, '小明', {'name': '小張'}]
    

    這就證明了深拷貝後的列表已經與原先的列表無關了。

  2. 補充:上面我們說的深拷貝後的列表與原列表沒有任何聯繫了,其實並不然,python解釋器做了優化的,兩個列表中的不可變數據類型指向仍爲同一個值,但是可變數據類型就是各自的互不影響。
    在這裏插入圖片描述

4. 思考
此時是深copy還是淺copy

l1 = [1, 2, '小紅', {'name': '夏天'}]
l2 = l1[:]

l1[-1]['name'] = '冬天'
print(l1)
print(l2)

答案是:淺拷貝

結語:深拷貝與淺拷貝在面試時會問,所以還是得分清兩者之間的區別,本章知識點到這裏結束。覺得博主講的還算不錯的可以點個贊,你們的鼓勵是我最大的動力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章