首页 > 技术文章 > python中的深浅拷贝问题

scaven-01 2020-04-04 14:22 原文

1.浅拷贝

1.1 对于无嵌套类型的浅复制

L = [1, 'Tom', '成都']
L1 = L.copy()    # 内存地址不一样

L[1] = '上海'
L1[2] = 'Hello'
L1.append('##')

print(L)    # [1, '上海', '成都']
print(L1)   # [1, 'Tom', 'Hello', '##']

1.2 对于有嵌套类型的浅复制

L = [1, 'Tom', [22, '成都']]
L1 = L.copy()   # 外层内存地址不一样,嵌套部分的内存地址一样

L1[2][0] = 'Hello'
L[2].append('##')

print(L)    # [1, 'Tom', ['Hello', '成都', '##']]
print(L1)   # [1, 'Tom', ['Hello', '成都', '##']]

2.深复制

​ 跟浅复制不一样的是,深复制不仅复制了内存空间的内容,更复制了内存空间后的指向,即通过深复制后的两个列表没有一点儿关联关系

import copy
L = [1, 'Tom', [22, '成都']]
L1 = L.deepcopy()   # 外层和嵌套内层的内存地址都不一样

L1[2][0] = 'Hello'
L[2].append('##')

print(L)    # [1, 'Tom', [22, '成都', '##']]
print(L1)   # [1, 'Tom', ['Hello', '成都']]

3.总结:

无论对于深拷贝还是浅拷贝,对于无嵌套的列表来说,对拷贝前的源列表或拷贝后的新列表的修改都不应该另一个列表的元素;而对于有嵌套的列表的来说,浅拷贝对嵌套列表的修改将影响两个列表的值;深拷贝则不影响。

浅拷贝:嵌套的可变数据类型是同一个

深拷贝:嵌套的可变数据类是不是同一个

4.赋值运算和切片

L = [1, '#', ['Tom', '上海']]
L1 = L          # 内存地址一模一样

L[1] = 4
del L1[2][0]

print(L)   # [1, 4, ['上海']]
print(L1)  # [1, 4, ['上海']]

2.切片

# 切片等同于浅复制
L = [1, '#', ['Tom', '上海']]
L1 = L[:]  # 外层内存地址不一样,嵌套部分内存地址一样
print(id(L))    # 139780854130760,外层内存地址不一样
print(id(L1))   # 139780854131016

print(id(L[2]))   # 139780855161544,嵌套部分内存地址一样
print(id(L1[2]))  # 139780855161544

L[1] = 4 
print(L)        # [1, 4, ['Tom', '上海']]
print(L1)       # [1, '#', ['Tom', '上海']]

del L1[2][0]    
print(L)       # [1, 4, ['上海']]
print(L1)      # [1, '#', ['上海']]

推荐阅读