Python基础之六:深浅拷贝问题

Python基础之六:深浅拷贝问题

一、对象赋值

1、代码
l1 = [1, '晴朗', [2, '小明']]
l2 = l1
print(l1 is l2)#True
l1[2][0] = 3
print(l2)#[1, '晴朗', [3, '小明']]
l1.append(4)
print(l2)#[1, '晴朗', [3, '小明'], 4]
2、图解

在这里插入图片描述

3、分析

1、创建了一个名为l1的变量,这个变量指向一个list对象
2、把l1的值赋值给l2,那么l2变量将指向l1变量对应的对象(内存地址),可以理解为,对象的赋值都是进行对象引用(内存地址)传递,也就是说"l1 is l2l",“l1[i] is l2[i]”
3、由于l1和l2指向同一个对象,所以对l1的任何修改都会体现在l2上

二、浅拷贝

1、代码
l1 = [1, '晴朗', [2, '小明']]
l2 = l1.copy()
print(l1 is l2)#False
l1[2][0] = 3
print(l2)#[1, '晴朗', [3, '小明']]
l1.append(4)
print(l2)#[1, '晴朗', [3, '小明']]
print(l1[2][0] is l2[2][0])#True
2、图解

在这里插入图片描述

3、分析

1、创建了一个名为l1的变量,这个变量指向一个list对象
2、通过copy模块里面的浅拷贝函数copy(),对l1指向的对象进行浅拷贝,然后浅拷贝生成的新对象赋值给l2变量
2.1、浅拷贝会创建一个新的对象,这个例子中"l1 is not l2"
2.2、但是,对于对象中的元素,浅拷贝就只会使用原始元素的引用(内存地址),也就是说"l1[i] is l2[i]"
3、由于l1和l2不指向同一个对象,但在拷贝时生成的对象与原来被拷贝对象中的元素分别指向同一个内存地址,所以对l1的元素任何修改都会体现在l2上,但对l1的单独操作不会引起l2变化(如添加元素)

三、深拷贝

1、代码
import copy #导入copy模块
l1 = [1, '晴朗', [2, '小明']]
l2 = copy.deepcopy(l1)
print(l1 is l2)#False
l1[2][0] = 3
print(l2)#[1, '晴朗', [2, '小明']]
l1.append(4)
print(l2)#[1, '晴朗', [2, '小明']]
print(l1[0] is l2[0])#True
print(l1[2] is l2[2])#False
2、图解

在这里插入图片描述

3、分析

1、创建了一个名为l1的变量,这个变量指向一个list对象
2、通过copy模块里面的浅拷贝函数deepcopy(),对l1指向的对象进行深拷贝,然后深拷贝生成的新对象赋值给l2变量
2.1、深拷贝会创建一个新的对象,这个例子中"l1 is not l2"
2.2、但是,对于对象中的元素,深拷贝都会重新生成一份,而不是简单的使用原始元素的引用(内存地址)
3、由于l1和l2不指向同一个对象,且l1和l2对象中的元素也不指向同一个内存地址,所以对l1的任何修改都不会体现在l2上

四、总结

1、Python中对象的赋值都是进行对象引用(内存地址)
2、传递/使用copy.copy(),可以进行对象的浅拷贝,它复制了对象,但对于对象中的元素,依然使用原始的引用
3、如果需要复制一个容器对象,以及它里面的所有元素(包含元素的子元素),可以使用copy.deepcopy()进行深拷贝
4、对于非容器类型(如数字、字符串、和其他’原子’类型的对象)没有被拷贝一说
5、如果元祖变量只包含原子类型对象,则不能深拷贝(没有意义,结果都一样),看下面的例子:

import copy #导入copy模块
t1 = (1, '晴朗', 2, '小明')
t2 = copy.copy(t1)
print(t1 is t2)#True
import copy #导入copy模块
t1 = (1, '晴朗', 2, '小明')
t2 = copy.deepcopy(t1)
print(t1 is t2)#True
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值