[每日一题]8、Python中的深拷贝和浅拷贝

点击上方Python3X”,选择“置顶或者星标

第一时间收到精彩推送!


Python Every Day, 第 8 天



拷贝说白了就是复制。对变量操作有赋值、拷贝等方法。他们之间是有区别的。


赋值


就是把一个对象的引用(在内存中的存储地址)和变量进行关联起来。可以通过id(对象) 查看其内存地址。


 
 
a = 'abc'b = a  #print(id(a), id(b)) # 20636768 20636768
b = a #
print(id(a), id(b)) # 20636768 20636768


如上,将变量a 赋值给b。其实是将a和b都是指向了字符串abc的内存地址(a和b是同一个引用),可以通过id()函数发现他们的内存空间地址是一样的。


浅拷贝


拷贝对象并给其分配新的内存。但是只会拷贝父对象,也就是第一层数据(后面代码解释)


通过 变量.copy()  进行浅拷贝。


 
 
# 定义一个变量aa = ['a', 1, 'd', ['z', 'x', 'c']]# b 浅拷贝了ab = a.copy()print(a) # ['a', 1, 'd', ['z', 'x', 'c']]print(b) # ['a', 1, 'd', ['z', 'x', 'c']]#  打印各自的内存地址,发现各不相同。证明了浅拷贝会分配一个新的内存地址print(id(a))  # 2767408print(id(b)) # 121575744# 修改a中的第一个元素为'A'a[0] = 'A'print(a)  # ['A', 1, 'd', ['z', 'x', 'c']]print(b) # ['a', 1, 'd', ['z', 'x', 'c']]   发现b并没有受影响# 修改第四个元素中的第一个元素,将z 修改成 Qa[3][1] = 'Q'print(a)  # ['A', 1, 'd', ['z', 'Q', 'c']]print(b)  # ['A', 1, 'd', ['z', 'Q', 'c']]  发现b也被修改了。why?print(id(a[3]))  # 2766208print(id(b[3])) # 2766208
a = ['a'1'd', ['z''x''c']]
# b 浅拷贝了a
b = a.copy()

print(a) # ['a', 1, 'd', ['z', 'x', 'c']]
print(b) # ['a', 1, 'd', ['z', 'x', 'c']]
#  打印各自的内存地址,发现各不相同。证明了浅拷贝会分配一个新的内存地址
print(id(a))  # 2767408
print(id(b)) # 121575744

# 修改a中的第一个元素为'A'
a[0] = 'A'
print(a)  # ['A', 1, 'd', ['z', 'x', 'c']]
print(b) # ['a', 1, 'd', ['z', 'x', 'c']]   发现b并没有受影响

# 修改第四个元素中的第一个元素,将z 修改成 Q
a[3][1] = 'Q'
print(a)  # ['A', 1, 'd', ['z', 'Q', 'c']]
print(b)  # ['A', 1, 'd', ['z', 'Q', 'c']]  发现b也被修改了。why?

print(id(a[3]))  # 2766208
print(id(b[3])) # 2766208


如上修改a中的第一个元素。b不会被修改。但是修改 第四个元素中的第一个元素。b却被影响了。这就是前面说的浅拷贝只会拷贝第一层数据。

第二层['z', 'Q', 'c']并没有拷贝成功。

这个时候b中的['z', 'Q', 'c'] 的内存地址和a中的['z', 'Q', 'c']内存地址是一样的。 (浅拷贝只是把这个第二层的引用拷贝过来了。)。所以a中第二层的数据发生变化,b中的数据也会跟着变化。

可以通过id() 进行验证。

 
 
print(id(a[3]))  # 2766208print(id(b[3])) # 2766208# 2766208
print(id(b[3])) # 2766208


深拷贝


深拷贝就是对对象的完全拷贝,不管你有多少层,数据都不会共享。

深拷贝需要引入copy模块。import copy

还是拿上面的数据我们进行演示。

 
 
import copya = ['a', 1, 'd', ['z', 'x', 'c']]b = copy.deepcopy(a)print(a) # ['a', 1, 'd', ['z', 'x', 'c']]print(a) # ['a', 1, 'd', ['z', 'x', 'c']]#  变量的内存空间地址print(id(a)) # 120265424print(id(b)) # 15809072print(a[-1])# 最后一个元素(['z', 'x', 'c'])的内存地址print(id(a[-1])) # 16171936print(id(b[-1])) # 120265344# 修改a[0] = 'A'a[3][0] ='Q'print(a) # ['A', 1, 'd', ['Q', 'x', 'c']]# 深拷贝中第二层数据也是独立的,不会被修改print(b) # ['a', 1, 'd', ['z', 'x', 'c']]

a = ['a'1'd', ['z''x''c']]
b = copy.deepcopy(a)

print(a) # ['a', 1, 'd', ['z', 'x', 'c']]
print(a) # ['a', 1, 'd', ['z', 'x', 'c']]
#  变量的内存空间地址
print(id(a)) # 120265424
print(id(b)) # 15809072
print(a[-1])
# 最后一个元素(['z', 'x', 'c'])的内存地址
print(id(a[-1])) # 16171936
print(id(b[-1])) # 120265344

# 修改
a[0] = 'A'
a[3][0] ='Q'
print(a) # ['A', 1, 'd', ['Q', 'x', 'c']]
# 深拷贝中第二层数据也是独立的,不会被修改
print(b) # ['a', 1, 'd', ['z', 'x', 'c']]


往期Python Every Day


[每日一题]7、Python中的super()函数

 [每日一题]6、Python中的可变参数

[每日一题]5、Python中的lambda表达式

[每日一题]4、Python中的迭代器

[每日一题]3、Python实现删除list中重复元素的几种方式

[每日一题]2、Python中的类的定义和装饰器@classmethod与@staticmethod

[每日一题] 1、Python中的可变对象与不可变对象


640?



感谢您的阅读


640?wx_fmt=gif


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值