python 指標拷貝,淺拷貝和深拷貝

張國平發表於2020-03-09

和上文一樣,還是一些基礎知識。

首先對於不可變型別int,string,float,tuple,並不用擔心拷貝問題,可以認為每次拷貝時候都是重新建立記憶體空間來存放,修改新的值不會影響原來的;兩個除了值一樣沒有相關。


對於可變型別Dict set list,還有例項物件,類一些,拷貝時候要考慮指標拷貝,淺拷貝和深拷貝的情況。


- 指標拷貝 就是通常A = B,對於可變型別,這個複製是多了個指標,兩個A,B都是指向同一個記憶體空間,任何一個修改都會影響其他的。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
    def __str__(self):
        return "[{}:{}]".format(self.val, self.left)
NodeA = TreeNode('A')
NodeB = TreeNode('B')
NodeA.left = NodeB
print(NodeA)
NodeC = NodeA
print(NodeC)
print('指標複製,更新NodeC,同時更新原來NodeA')
NodeC.val = 'C'
NodeC.left = None
print(NodeA)
print(NodeC)

結果是:

[A:[B:None]]
[A:[B:None]]
指標複製,更新NodeC,同時更新原來NodeA
[C:None]
[C:None]


- 淺複製:需要import copy 庫實現,這裡是用了新的記憶體空間存放複製內容。但是如果複製內容裡有指向其他可變型別,該引用還是指向那個可變型別原來記憶體空間。

import copy
NodeA = TreeNode('A')
NodeB = TreeNode('B')
NodeA.left = NodeB
print(NodeA)
NodeC = copy.copy(NodeA)
print(NodeC)
print('淺複製,更新NodeC,不會更新原來NodeA,但是更新引用NodeC.left, 會影響NodeA.left')
NodeC.val = 'C'
NodeC.left.val = 'Cleft'
print(NodeA)
print(NodeC)

結果:

[A:[B:None]]
[A:[B:None]]
淺複製,更新NodeC,不會更新原來NodeA,但是更新引用NodeC.left, 會影響NodeA.left
[A:[Cleft:None]]
[C:[Cleft:None]]

- 深複製:需要import copy 庫實現,這裡是用了新的記憶體空間存放複製內容;如果裡面有指標指向可變型別空間,也會被一起復制。

import copy
NodeA = TreeNode('A')
NodeB = TreeNode('B')
NodeA.left = NodeB
print(NodeA)
NodeC = copy.deepcopy(NodeA)
print(NodeC)
print('深複製,更新NodeC,不會更新原來NodeA,更新NodeC.left, 不會影響NodeA.left')
NodeC.val = 'C'
NodeC.left.val = 'Cleft'
print(NodeA)
print(NodeC)

結果:

[A:[B:None]]
[A:[B:None]]
深複製,更新NodeC,不會更新原來NodeA,更新NodeC.left, 不會影響NodeA.left
[A:[B:None]]
[C:[Cleft:None]]


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2679238/,如需轉載,請註明出處,否則將追究法律責任。

相關文章