Python之深淺拷貝

                                         Python之深淺拷貝python


1、淺拷貝
ide

所謂淺拷貝,指的是對於某個對象,雖然建立了與該對象具備相同值的另外一個對象,可是,這兩個對象內部嵌套的對應子對象全都是同一個對象。簡單地說,外部進行了拷貝,內部沒有拷貝。函數

如下方式獲得的拷貝都是淺拷貝:spa

● 切片操做[:]對象

● 調用列表、字典、集合的方法copy()索引

● 調用內置函數List()、dict()、set(4.內存

● 調用標準庫模塊copy中的函數copy()it

import copy  # 導入標準庫模塊copy
L1 = [1,[1,2,3],6]
L2 = L1.copy() # [1, [1, 2, 3], 6] 使用list.copy()
L2 = L1[:] # [1, [1, 2, 3], 6] # 使用索引切片的方式
L2 = list(L1) #  [1, 2, 3], 6] # 使用list()函數賦值
L2 = copy.copy(L1) # [1, [1, 2, 3], 6]  # 調用標準庫模塊copy中的函數copy()

# 經過打印L1和L2的id能夠看出,L2只拷貝了L1的外部,造成了一個和L1具備相同值的對象
# L1和L2內部值的id全都相同,即引用的同一內存地址
print('L1_id:%d' % id(L1)) # L1_id:140024932419056
print('L2_id:%d' % id(L2)) # L2_id:140024932419456
print('L1[1]_id:%d' % id(L1[1])) # L1[1]_id:140024932419376
print('L2[1]_id:%d' % id(L2[1])) # L2[1]_id:140024932419376
print('id_L1[2] %d' % id(L1[2])) # id_L1[2] 9466624
print('id_L2[2] %d' % id(L2[2])) # id_L2[2] 9466624

# 淺拷貝,對於列表內部嵌套的可變類型對象,修改L1[1][1]值,L2[1][1]值也會跟着改變
# 實際上他們內部都引用着同一個內存id
L1[1][1] = 5
print(L1) # [1, [1, 5, 3], 6]
print(L2) # [1, [1, 5, 3], 6]
print('L1[1]_id:%d' % id(L1[1])) # L1[1]_id:140024932419376
print('L2[1]_id:%d' % id(L2[1])) # L2[1]_id:140024932419376

# 淺拷貝,對於列表內部的不可變類型對象,修改L1[2],
# 由於是不可變類型,那麼會從新調用一個值給予引用,L2[2]所以不受影響
L1[2] = 8
print(L1) # [1, [1, 5, 3], 8]
print(L2) # [1, [1, 5, 3], 6]
print('id_L1[2] %d' % id(L1[2])) # id_L1[2] 9466688
print('id_L2[2] %d' % id(L2[2])) # id_L2[2] 9466624


2、深拷貝class

所謂深拷貝,指的是:對於某個對象,建立與該對象具備相同值的另外一個對象,同時,這兩個對象內部嵌套的對應可變子對象全都不是同一個對象。簡單地說,外部和內部都進行了拷貝。import

深拷貝的方法:

● 調用標準庫模塊copy中的函數deepcopy()

import copy  # 導入標準庫模塊copy
L1 = [1,[1,2,3],6]
L2 = copy.deepcopy(L1) # [1, [1, 2, 3], 6]

# 經過打印L1和L2的內存地址能夠看出,其外部進行拷貝,L2是和L1具備相同值的新對象
# 對於內部嵌套的可變類型對象,L1[1]和L2[1]內存地址並不相同
# 對於內部嵌套的不可變類型對象,L1[2]和L2[2]內存地址相同,引用的同一內存地址
print('L1_id:%d' % id(L1)) # L1_id:139984573203792
print('L2_id:%d' % id(L2)) # L2_id:139984573203952
print('L1[1]_id:%d' % id(L1[1])) # L1[1]_id:139984573203472
print('L2[1]_id:%d' % id(L2[1])) # L2[1]_id:139984573204512
print('id_L1[2] %d' % id(L1[2])) # id_L1[2] 9466624
print('id_L2[2] %d' % id(L2[2])) # id_L2[2] 9466624

# 深拷貝,列表內部嵌套的可變類型對象,修改L1[1][1] 爲5不影響L2[1][1]的值,
# 深拷貝是將L1和L2內部可變類型對象的值引用的內存地址分開來
L1[1][1] = 5
print(L1) # [1, [1, 5, 3], 6]
print(L2) # [1, [1, 2, 3], 6]
print('L1[1]_id:%d' % id(L1[1])) # L1[1]_id:139984573203472
print('L2[1]_id:%d' % id(L2[1])) # L2[1]_id:139984573204512

# 深拷貝,對於列表內部不可變類型對象,修改L1[2] = 8,由於是不可變類型,因此將L1[2]從新賦值引用,不影響L2[2]
L1[2] = 8
print(L1) # [1, [1, 5, 3], 8]
print(L2) # [1, [1, 2, 3], 6]
print('id_L1[2] %d' % id(L1[2])) # id_L1[2] 9466688
print('id_L2[2] %d' % id(L2[2])) # id_L2[2] 9466624
相關文章
相關標籤/搜索