Python3浅拷贝与深拷贝

普通的复制

a = 6
b = 6
print(id(a),id(b))
2019039520736 2019039520736

由此可见是一个对象贴了两个标签 变量a与变量b是同指一个对象,这种现象普遍存在python多种数据类型,再看一下dict类型

mydict = {‘name’:‘feixueb’,‘language’:‘python’}
mydict1 = mydict
print(id(mydict),id(mydict1))
2019039909568 2019039909568

dict类型也是如此,这是用赋值的方式的假拷贝

copy函数复制

tomydict = mydict.copy()
print(id(mydict),id(tomydict))
2019039909568 2019040096760

用copy函数复制,发现mydict与tomydict所在两个不同的内存地址,由此可以推相测tomydict修改不会造成mydict修改,不妨进行实验看看

tomydict[‘name’] = ‘Feidisi’
print(mydict)
{‘name’: ‘Feidisi’, ‘language’: ‘python’}
print(tomydict)
{‘name’: ‘feixueb’, ‘language’: ‘python’}

结果的确如此,不妨再进行实验看看

dict_one = {‘name’:‘c1’,‘language’:[‘python’,‘c’,‘c++’]}
dict_two = dict_one.copy()
dict_two[‘language’].remove(‘c’)
dict_two
{‘name’: ‘c1’, ‘language’: [‘python’, ‘c++’]}
dict_one
{‘name’: ‘c1’, ‘language’: [‘python’, ‘c++’]}

为什么会这样?dict_one与dict_two明明是同一个对象,为什么dict_two修改会造成dict_one改变。以上事实说明,根据键修改值,若修改的是字符串,一个不跟随修改。而修改的是列表,另一个随着修改。不妨用id来查查看。

print(dict_one,dict_two)
2019039909496 2019040096544
id(dict_one[‘name’])
2019039888192
id(dict_two[‘name’])
2019039888192
id(dict_one[‘language’])
2019040102792
id(dict_two[‘language’])
2019040102792

其深层次的原因与python对象类型有关,python只存储基本的数据类型,如str,int等。对于不是基本数据类型的,如字典的值是列表,python不会重新开辟空间存储该列表,而是会用引用的方式,指向原来的那个值。故因此id(dict_one[‘language’]) 等于id(dict_two[‘language’])。
但读者会感到疑问,id(dict_one[‘name’]) 与 id(dict_two[‘name’])的值是字符串类型,是基本类型为什么在复制的时候不重新开辟区间。这是由python的机制有关,python在设计时把一些常用的数据类型,系统先给确定内存空间,而不是像c语言那般定义一个变量,就随机给其开辟一个地址。举例说明

id(5)
1724476560
id(6)
1724476592
a = 5
id(a)
1724476560
a = a + 1
id(a)
1724476592
再看字符串
id(‘akkakkaka’)
2019040041008
str = ‘akkakkaka’
id(str)
2019040041008

说明python事先会给一些常用的基本数据类型自动给定内存空间,但这一些常用的数据类型范围是有限的

id(‘hello world’)
2019040040624
str = ‘hello world’
id(str)
2019040040176
再看复杂数据类型
id([1,2,3,4,5])
2019040042376
list = [1,2,3,4,5]
id(list)
2019040103176

由此可见,这范围确实是有限的。至于这限度随着读者代码的阅读经验自己会熟悉。再回归前面 id(dict_one[‘language’]) 等于 id(dict_two[‘language’])就是这样,由于python会把一些常用的数据先给其分配空间。copy这种拷贝不彻底,我们可以称之为浅拷贝。有浅则有深之说

深拷贝(deep copy)

在python中有deep copy,不过需要import导入copy模块。我先给其(仅个人的观点)定义:深拷贝则就是深层次拷贝,完全拷贝。不妨测试看看。

import copy
dict_thr = copy.deepcopy(dict_one)
dict_thr
{‘name’: ‘c1’, ‘language’: [‘python’, ‘c++’]}
id(dict_one)
2019039909496
id(dict_thr)
2019040096472
id(dict_one[‘language’])
2019040102792
id(dict_thr[‘language’])
2019040103560
dict_thr[‘language’].append(‘akkak’)
dict_thr
{‘name’: ‘c1’, ‘language’: [‘python’, ‘c++’, ‘akkak’]}
dict_one
{‘name’: ‘c1’, ‘language’: [‘python’, ‘c++’]}

由上可知,深拷贝非常彻底。在实际运用中拷贝非常常见,因此合理利用三种拷贝则会在满足引用需要,来节省内存资源非常重要。

有问题请指正。原创不易,多谢点赞

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值