Python学习笔记之拷贝

本文通过一对夫妻开设银行账号的例子,形象地解释了浅拷贝与深拷贝的区别。浅拷贝只复制对象的第一层引用,深拷贝则会递归地复制所有层级的对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浅拷贝,深拷贝。我一听到这两个词就有点儿懵逼。怎么copy也分深浅了!??

为了弄清这浅拷贝和深拷贝到底是何方神圣,我仔细的将书本内容进行研读,终于理解了这两种拷贝的“水深”

为了说明这个问题,我们来举个栗子

现在有那么一对夫妻要到银行开设他们两个人的银行账号。
我们先新建一个通用账号,名字叫person。
然后分别为他俩拷贝一份属于他们自己的账号。

>>> person = ['name', ['savings', 100.00]]
>>> husband = person[:]   #切片复制
>>> wife = list(person)   #利用工厂函数
>>> [id(x) for x in person, husband, wife] #运用id()来显示每个对象的标识符
[11826320, 12223552, 11850936]

好的我们现在已经将银行账号创建好了,他们初始情况下是有100元。而且这三个账号的是不同的(它们的对象标识符不同)

现在我们试着写上husband和wife的名字,并且命令丈夫从银行账户中取走50元。我们看看这时候银行账号会发生什么?!

>>> husband[0] = 'jack'
>>> wife[0] = 'marry'
>>> husband, wife
(['jack', ['savings', 100.0]], ['marry', ['savings', 100.0]])
>>> husband[1][1] = 50.00
>>> husband,wife
(['jack', ['savings', 50.0]], ['marry', ['savings', 50.0]])

jack取走了50元后,不仅jack的账号减少了50元,同时marry的账号也减少了50元。这说明这个银行账号是他们俩人的联合账户。

为什么呢?我们明明复制了两个账户,他们的标识符不一样,为什么修改了一个,另外一个的值也会被修改呢?
原来这里的复制只是创建了一个引用而已。这就是所谓的浅拷贝!!

浅拷贝:创建一个类型跟原对象一样的新对象,它的内容是原来对象元素的引用
也就是说,jack和marry拷贝的银行账户是不同的,但是存款却是他们俩人共有的。

以下几种方式能够创建浅拷贝:

  1. 完全切片操作[:]
  2. 利用工厂函数,比如list()、dict()等
  3. 使用copy模块的copy函数

看到这里,我们知道他们两个人的账号是因为浅拷贝,所以他们的账户金额是共享的。

那么又有一个问题出来了!

为什么他们的名字不共享呢?明明两个账户的内容都是联合账户的引用啊!?

原来是因为对象类型的不同。名字是不可变类型(字符串类型),账户是可变类型(列表类型)所以名字是新建的字符串对象,而账户金额是引用

PS:我来回顾一下那些是不可变类型。
1.数字 2.字符串 3.元祖(元祖中不包含列表)

现在我们要为这对夫妇创建他们的个人账户(不共享账户金额),这会儿应该怎么做呢?

答,深拷贝!!

>>> person = ['name', ['savings', 100.00]]
>>> husband = person[:]   #切片复制
>>> import copy
>>> wife = copy.deepcopy(person)   #使用深拷贝
>>> [id(x) for x in person, husband, wife] #运用id()来显示每个对象的标识符
[11826320, 12223552, 11850936]
>>> husband[0] = 'jack'
>>> wife[0] = 'marry'
>>> husband, wife
(['jack', ['savings', 100.0]], ['marry', ['savings', 100.0]])
>>> husband[1][1] = 50.00
>>> husband,wife
(['jack', ['savings', 50.0]], ['marry', ['savings', 100.0]])
#husband和wife中 名字 和 账户金额 的对象标识符
>>> [id(x) for x in huaband]
[12191712,11826280]
>>> [id(x) for x in wife]
[12114080,12224792]

我们可以看到,运用深拷贝就可以创建个人账户了!

我们现在来总结一下
浅拷贝:浅拷贝中可变数据类型是拷贝对象的可变数据类型的引用,而不可变数据类型却是一个新对象
深拷贝:深拷贝中不管数据类型如何,拷贝后都会创建一个新对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值