浅拷贝 深拷贝

1. 浅拷贝:只拷贝第一层,更深层的还指向原有的内存地址。

2. 深拷贝: 递归拷贝多层。

1. 先看一例子:

import copy

a = [1, 3, 4]

f = a
print(id(a))
print(id(f))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
1841649924552
1841649924552

将变量a 赋值给变脸f,其实是将变量f 指向变量a对应值得内存地址。

 

浅拷贝:

import copy

a = [1, 3, 4]
b = [2, 5]
c = [a, b]
d = copy.copy(c)
print('c的内存地址', id(c))
print('d的内存地址', id(d))
print('c的第一个元素内存地址', id(c[0]))
print('d的第一个元素内存地址', id(d[0]))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
c的内存地址 1507477928264
d的内存地址 1507478038024
c的第一个元素内存地址 1507477928392
d的第一个元素内存地址 1507477928392

d元素是经过浅拷贝c元素得来的,因此d元素的内存地址与c元素的内存地址不相同,就是拷贝了一份c的元素在内存中重新开辟一段空间存储,但是浅拷贝不拷贝内层的引用。因此

c元素的第一个元素值得内存地址与d元素的一个元素值得内存地址相同。

深拷贝:

import copy

a = [1, 3, 4]
b = [2, 5]
c = [a, b]
e = copy.deepcopy(c)
print('c的内存地址', id(c))
print('e的内存地址', id(e))
print('c的第一个元素内存地址', id(c[0]))
print('e的第一个元素内存地址', id(e[0]))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
c的内存地址 2093738014856
e的内存地址 2093738015048
c的第一个元素内存地址 2093738014984
e的第一个元素内存地址 2093738014024

可以看出,深拷贝内层元素的值也被重新拷贝一份,而不是执行原来的引用。

对于元组的拷贝

import copy


a = (1, 3, 4)
b = copy.copy(a)
print(id(a))
print(id(b))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
1950885994784
1950885994784

因为元祖是不可变类型,那么久意味着数据一定不能修改,因此使用浅拷贝时,它会自动判断,如果是元祖,就直接指向,不会重新拷贝一份。

如果是深拷贝呢

import copy


a = (1, 3, 4)
b = copy.deepcopy(a)
print(id(a))
print(id(b))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
2048102687008
2048102687008

还是直接指向。

再看例子

import copy


a = [1, 3, 4]
b = [2, 5]
c = (a, b)
d = copy.copy(c)
print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
1698151178632
1698151178632
1698152560328
1698152560328

结论,对于元祖的浅拷贝,即使元祖中存在可变元素 如列表,也都是指向。

那么深拷贝呢

import copy


a = [1, 3, 4]
b = [2, 5]
c = (a, b)
d = copy.deepcopy(c)
print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
2626026493576
2626026495560
2626026321992
2626026322056

结论; 对于深拷贝,若元祖中存在可变元素,那么深拷贝就会重新拷贝一份。

那么总结一个元祖的拷贝:

如果用浅拷贝 深拷贝对一个全部都是不可变类型的数据进行拷贝,那么他们的结果相同,都是指向引用。

如果拷贝的是一个不可变类型的数据,但是内层存在可变类型时,浅拷贝是指向引用,深拷贝是重新拷贝一份。

其他的操作也是拷贝(列表的切片,是浅拷贝)

 字典的拷贝

先说一下字段的存储原理,创建一个字典时,字典的key在字典中存储,但是对应的值存储的是值对应的引用。

所以说,对于字典的浅拷贝,拷贝出来的字典的值,也是执行引用。

import copy


a = {'k1': 'v1', 'k2': 'v2', 'k3': [1, 3, 5]}
b = copy.copy(a)
print(id(a))
print(id(b))
a['k3'].append(9)
print(a)
print(b)

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
2245390036616
2245396227592
{'k2': 'v2', 'k3': [1, 3, 5, 9], 'k1': 'v1'}
{'k2': 'v2', 'k3': [1, 3, 5, 9], 'k1': 'v1'}

深拷贝

import copy


a = {'k1': 'v1', 'k2': 'v2', 'k3': [1, 3, 5]}
b = copy.deepcopy(a)
print(id(a))
print(id(b))
a['k3'].append(9)
print(a)
print(b)

G:\envs\flaskenv\Scripts\python.exe G:/workspace/albumy-master/11.py
2422065983112
2422068394568
{'k1': 'v1', 'k2': 'v2', 'k3': [1, 3, 5, 9]}
{'k1': 'v1', 'k2': 'v2', 'k3': [1, 3, 5]}

转载于:https://www.cnblogs.com/yuqiangli0616/p/10291252.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值