从底层分析python中深拷贝和浅拷贝区别

深浅拷贝在python中经常使用,其区别的外在表现是:

使用浅拷贝,当原容器对象中可变对象中有元素发生变化,拷贝得到的对象也会变化。而使用深拷贝时,不会有这种问题。

听起来有一点难理解,看例子比较直观:

浅拷贝

>>> list1 = [['a', 'b'], 1, 2]

>>> list3 = copy.copy(list1)

>>> list3

[['a', 'b'], 1, 2]

>>> list1[0][0] = 'c' #修改lsit1

>>> list3

[['c', 'b'], 1, 2] #list3也变了

深拷贝

>>> list1 = [['a', 'b'], 1, 2]

>>> list3 = copy.deepcopy(list1)

>>> list1[0][0] = 'c' #修改list1

>>> list3

[['a', 'b'], 1, 2] #list3没有变

但是为什么会这样,可以由下图解释:


当我们声明list1 = [['a', 'b'], 1, 2]时,计算机做了这些事:

1、在内存中开辟一段空间,用来存放字符a,b和数字1,数字2

2、在内存开辟一段空间,用来存放一个列表,我们称为list2。list2中存放两个指针,分别指向字符a和b

3、在内存开辟一段空间,用来存放一个列表lsit1,list1中存放三个指针,分别指向list2,数字1和数字2

当执行浅拷贝lsit3 = copy.copy(list1)时,计算机开辟一段内存给list3,list3保存三个指针,分别指向list2,数字1和数字2。当执行list1[0][0] = 'c'时,list2对象修改了,而list3的第一个指针指向list2,所以我们看到list3的第一个元素也变了。

当执行深拷贝lsit4 = copy.copy(list1)时,计算机开辟一段内存给list4,和浅拷贝不同的是,计算机同时开辟一段空间给新的列表,我们称为lsit5。list5中保存2个指针,分别指向字符a和b。

同时list4保存三个指针,分别指向list5,数字1和数字2。此时,当执行list1[0][0] = 'c'时,list2对象修改了,但list4的第一个指针指向list5,list5并没有修改,所以list4没有改变。

总结:深拷贝会把可变对象也拷贝一份,而浅拷贝不会。

上面例子中说的是列表(可变对象)的拷贝,那对于元组,字符等不可不对象呢?

答案是,对不可不对象,其实不存在深浅拷贝的问题。无论怎么拷贝,效果都是新建立一个指向不可变对象的指针而已。

>>> a = 'f'

>>> b = copy.copy(a)

>>> id(a)

4302389968

>>> id(b)

4302389968

>>> c = copy.deepcopy(a)

>>> id(c)

4302389968

>>> 

>>> d = a

>>> id(a)

4302389968



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值