生信之旅

扫码分享下吧!
分享

Python不得不会的知识点-赋值与拷贝

这段时间在写一个软件,但是近期在测试时发现了有问题,经过多次测试和排查,终于找到了问题所在,就是Python的对象引用及拷贝问题。下面讲解梳理下这方面的知识点:

  • 直接赋值:引用当前对象,不涉及新内存的创建
  • 浅拷贝:仅拷贝当前对象,不拷贝当前对象的子对象
  • 深拷贝:当前对象及其子对象均拷贝

下面用例子来讲解这几种方法的区别

一、直接赋值

a = [1,2,3]
b = a
print("更改前:",a,b)
b.append(4)
print("更改后:",a,b)

输出结果如下:

更改前: [1, 2, 3] [1, 2, 3]
更改后: [1, 2, 3, 4] [1, 2, 3, 4]

这里我们可以看出,当b更改时,a也随着更改,因为b只是a的一个引用,相当于a的别名。

图1:直接赋值图示

二、浅拷贝

a = [1,2,3]
b = a.copy() # 或者b = a[:]也可以
print("更改前:",a,b)
b.append(4)
print("更改后:",a,b)


# 为探究子对象的拷贝情况,这里用字典来说明
c = {'a':[1,2,3]}
d1 = c.copy()
d2 = c.copy()
print("更改前:",c,d1,d2)

d1['a'] = 2
d2['a'][0] = 0
print("更改后:",c,d1,d2)

输出结果如下:

更改前: [1, 2, 3] [1, 2, 3]
更改后: [1, 2, 3] [1, 2, 3, 4]

更改前: {'a': [1, 2, 3]} {'a': [1, 2, 3]} {'a': [1, 2, 3]}
更改后: {'a': [0, 2, 3]} {'a': 2} {'a': [0, 2, 3]}

这里可以看出,浅拷贝的话对当前对象来说,相当于备份了一份,更改哪一份对另一份都没有影响(例如a与b,c与d1),若当前对象还有子对象的话,浅拷贝时,子对象相当于引用,并没有拷贝(例如c与d2),所以当前对象的子对象更改时,浅拷贝对象的子对象也会更改。

图2:浅拷贝图示

三、深拷贝

import copy  # 深拷贝需要引入copy包

c = {'a':[1,2,3]}
d1 = copy.deepcopy(c)
d2 = copy.deepcopy(c)
print("更改前:",c,d1,d2)

d1['a'] = 2
d2['a'][0] = 0
print("更改后:",c,d1,d2)

输出结果如下:

更改前: {'a': [1, 2, 3]} {'a': [1, 2, 3]} {'a': [1, 2, 3]}
更改后: {'a': [1, 2, 3]} {'a': 2} {'a': [0, 2, 3]}

这里可以看出,深拷贝时,当前对象及其子对象均拷贝了,一份拷贝修改后,不会对原始数据造成影响。

图3:深拷贝图示

版权声明:本文转载请注明出处!

最新评论:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

captcha

公告栏

有任何问题均可以在文章页面留言!或者邮件 burning@burning.net.cn 欢迎关注微信公众号 “生信之旅”,每天均可在菜单栏领取外卖红包、支付宝红包!最高20元!

服务器推荐

欢迎关注公众号

欢迎关注生信之旅