拷贝对象的意义在于:如果需要在不更改源数据的情况下,修改数据,此时需要一个拷贝对象
python提供copy来完成这样的拷贝
1、赋值
lst = [1, ['a', 'b']]
L = lst
lst.insert(1, 2)
lst[2].append('c')
print('lst:', lst, 'id:', id(lst))
print('L:', L, 'id:', id(L))
print('lst中元素的value和id')
for i in lst:
print('value:', i, 'id:', id(i))
print('L中元素的value和id')
for i in L:
print('value:', i, 'id:', id(i))
结果为:
lst: [1, 2, ['a', 'b', 'c']] id: 38425416
L: [1, 2, ['a', 'b', 'c']] id: 38425416
lst中元素的value和id
value: 1 id: 1588096032
value: 2 id: 1588096064
value: ['a', 'b', 'c'] id: 38425224
L中元素的value和id
value: 1 id: 1588096032
value: 2 id: 1588096064
value: ['a', 'b', 'c'] id: 38425224
从上面的结果得知,赋值并没有为 L 建立新的内存空间,lst 的 value 和 id 以及其元素的 value 和 id 都是与 L 相同的,说明只是将 L 指向 lst,新的对象没有被创建,你可以理解为一个人有2个名字,虽然不同,但都是同一个人
2、浅拷贝
import copy
lst = [1, ['a', 'b']]
L = copy.copy(lst)
print('数据操作前lst和L的id值')
print('id(lst):', id(lst), 'id(L):', id(L))
lst.insert(1, 2)
lst[2].append('c')
print('操作后:')
print('lst:', lst, 'id:', id(lst))
print('L:', L, 'id:', id(L))
print('lst中元素的value和id')
for i in lst:
print('value:', i, 'id:', id(i))
print('L中元素的value和id')
for i in L:
print('value:', i, 'id:', id(i))
结果:
数据操作前lst和L的id值
id(lst): 38028168 id(L): 38029448
操作后:
lst: [1, 2, ['a', 'b', 'c']] id: 38028168
L: [1, ['a', 'b', 'c']] id: 38029448
lst中元素的value和id
value: 1 id: 1589996576
value: 2 id: 1589996608
value: ['a', 'b', 'c'] id: 38027976
L中元素的value和id
value: 1 id: 1589996576
value: ['a', 'b', 'c'] id: 38027976
从结果得知,L 的 id 与 lst 的 id 在数据操作前就已经不同了,说明浅拷贝为拷贝对象 new 了一个新对象,继续观察可以发现不同的结果有,lst新增数据 2,而 L并没有相应增加(因为它们属于两个不同的对象了)
3、深拷贝
import copy
lst = [1, ['a', 'b']]
L = copy.deepcopy(lst)
print('数据操作前lst和L的id值')
print('id(lst):', id(lst), 'id(L):', id(L))
lst.insert(1, 2)
lst[2].append('c')
print('操作后:')
print('lst:', lst, 'id:', id(lst))
print('L:', L, 'id:', id(L))
print('lst中元素的value和id')
for i in lst:
print('value:', i, 'id:', id(i))
print('L中元素的value和id')
for i in L:
print('value:', i, 'id:', id(i))
结果:
数据操作前lst和L的id值
id(lst): 34096008 id(L): 34097288
操作后:
lst: [1, 2, ['a', 'b', 'c']] id: 34096008
L: [1, ['a', 'b']] id: 34097288
lst中元素的value和id
value: 1 id: 1588096032
value: 2 id: 1588096064
value: ['a', 'b', 'c'] id: 34095816
L中元素的value和id
value: 1 id: 1588096032
value: ['a', 'b'] id: 34097224
我们对比浅拷贝来看,深拷贝也是新建了一个内存地址,不可变对象 1 还是 1,但可变对象['a', 'b']也为它新增了一个内存地址,浅拷贝中是没有的,所以浅拷贝中,list数据的改变是同步的,而深拷贝是不一样的结果。
结论:
- 直接赋值并没有新建对象,只是多了一个引用名
- 深、浅拷贝都是对源对象的复制,占用不同的内存空间。区别在于浅拷贝对可变对象的是完全复制,深拷贝是新建内存空间,只复制其值
网友评论