shallow copy and deep copy(淺拷貝與深拷貝) -python


首先先看一下copy的官方介紹:Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations (explained below).
意思就是:Python中的賦值語句不復制對象,它們在目標和對象之間創建綁定。 對於可變或包含可變項的集合,有時需要一個副本,因此可以更改一個副本而不更改另一個副本。 該模塊提供了通用的淺層和深層複製操作(如下所述)。
後面所指父對象爲容器,即存儲數據的結構,子對象爲數據

直接賦值

直接賦值相當於引用(別名)
在這裏插入圖片描述
其父對象和子對象均指向指向同一個對象,下面對直接賦值進行增刪改的測試

a = [1,2,3,4]
b = a
print(b) => [1,2,3,4]
#增加
a.append(5)
print(a,b) => [1,2,3,4,5]  [1,2,3,4,5]
#刪除
del(a[0])
print(a,b) => [2,3,4,5]  [2,3,4,5]
#修改
a[-1] = 10
print(a,b) => [2,3,4,10]  [2,3,4,10]

同理,改變b也能夠達到一樣的效果,即直接賦值,無論做什麼修改都會隨着改變 (對容易的操作-增刪 對數據的操作-修改)

淺拷貝

a 和 b 是一個獨立的對象,但他們的子對象還是指向統一對象(是引用)
在這裏插入圖片描述
進行增刪改的測試

import copy
a = [1,2,3,4]
b = copy.copy(a)
print(a,b)  => [1,2,3,4] [1,2,3,4]
#增加
a.append(5)
print(a,b) => [1,2,3,4,5]  [1,2,3,4]
#刪除
del(a[0])
print(a,b) => [2,3,4,5]  [1,2,3,4]
#修改
a[-1] = 10
print(a,b) => [2,3,4,10]  [1,2,3,4]

複合對象

import copy
a = [[1,2],3,4]
b = copy.copy(a)
print(a,b)  => [[1,2[,3,4] [[1,2],3,4]
#增加
a.append(5)
print(a,b) => [[1,2],3,4,5]  [[1,2],3,4]
#刪除
del(a[2])
print(a,b) => [[1,2],3,5] [[1,2],3,4]
#修改
a[0][0] = 88
print(a,b) => [[88,2],3,5]  [[88,2],3,4]

可以看出,copy僅拷貝對象本身,不對其中的子對象進行拷貝,故對子對象的修改也會隨着修改(針對嵌套的數據,即複合對象

深拷貝

真正意義上的複製,即從新開闢一片空間
a 和 b 完全拷貝了父對象及其子對象,兩者是完全獨立的
在這裏插入圖片描述
淺拷貝與深拷貝的區別:
The difference between shallow and deep copying is only relevant for compound objects(僅與複合對象相關) (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
    經常存在深拷貝,但不存在淺拷貝的問題
    Two problems often exist with deep copy operations that don’t exist with shallow copy operations:
  • Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
  • Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.(用於共享的數據,造成空間浪費)

使用深拷貝的會避免以下問題
The deepcopy() function avoids these problems by:

  • keeping a memo dictionary of objects already copied during the current copying pass;
  • letting user-defined classes override the copying operation or the set of components copied.

注:

Shallow copies of dictionaries can be made using dict.copy(), and of lists by assigning a slice of the entire list, for example, copied_list = original_list[:].
可以使用dict.copy()和列表的淺層副本,通過分配整個列表的切片,例如,copied_list = original_list [:]。

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, array, or any similar types. It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle module.
此模塊不復制類型,如模塊,方法,堆棧跟蹤,堆棧幀,文件,套接字,窗口,數組或任何類似類型。 它通過返回原始對象來“複製”函數和類(淺和深); 這與pickle模塊處理這些方式兼容。

官方鏈接
https://docs.python.org/3/library/copy.html

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