Python的浅拷贝和深拷贝


面试的时候被问到“知道浅拷贝和深拷贝吗?”
“…” “os:什么…没听过…”
于是,今天来扒一扒这个知识点。

前提

浅拷贝和深拷贝,其实就是数据拷贝。
- 当拷贝的是不可变数据类型(数值、字符串、元组),不管是深拷贝和浅拷贝,都指向的是同一地址;

import copy
a = 1
b = copy.copy(a)
c = copy.deepcopy(a)
print(a, id(a))
print(b, id(b))
print(c, id(c))

运行结果:

1 4362989344
1 4362989344
1 4362989344

- 当拷贝的对象是可变数据类型(列表、字典),浅拷贝深拷贝才生效。

普通的变量赋值

我们平常使用的变量赋值,就是浅拷贝。即两个变量共享同一个内存块,相同的内存地址,一旦值发生改变,另外一个变量的值也会跟随着一起变化。

# 变量赋值
li = ['123', 5, 'abc', 9]
a = li
print(id(li))
print(id(a))

# 修改a的数据
a[1] = ['333']
print(id(li), li)
print(id(a), a)

运行结果:

4351771104
4351771104
4330881504 ['123', ['333'], 'abc', 9]
4330881504 ['123', ['333'], 'abc', 9]

常规的变量赋值共享一个代码块,内存地址相同,值发生改变时同一个内存地址的值都会跟着改变。

浅拷贝和深拷贝

copy.copy() – 浅拷贝,重新分配内存,只拷贝父对象,不会拷贝对象的内部的子对象;
copy.deepcopy() – 深拷贝,重新分配内存,拷贝对象及其所有子对象;

浅拷贝和深拷贝的区别

  • 当拷贝的对象无复杂子对象时:
    对于常规的字典或者列表使用copy模块的深拷贝或者浅拷贝,两者并没有区别。
import copy
print('使用浅拷贝:')
a = ['A', 'B', 'C', 'D']
# 使用浅拷贝
b = copy.copy(a)
b[1] = 42
print(id(a), a)
print(id(b), b)
print('****************************')

print('使用深拷贝:')
a = ['A', 'B', 'C', 'D']
# 使用深拷贝
b = copy.deepcopy(a)
b[1] = 42
print(id(a), a)
print(id(b), b)

运行结果:

使用浅拷贝:
4386645008 ['A', 'B', 'C', 'D']
4386646288 ['A', 42, 'C', 'D']
****************************
使用深拷贝:
4386645728 ['A', 'B', 'C', 'D']
4386645008 ['A', 42, 'C', 'D']
  • 当字典或者列表中还有包含有子对象时:
    使用copy模块的深拷贝和浅拷贝的话,结果就大不相同了。
import copy
print('使用浅拷贝:')
a = ['A', 'B', ['C', 'D', 'E'], 'F']
# 使用浅拷贝
b = copy.copy(a)
b[2][1] = 42
print(id(a), a)
print(id(b), b)
print('********************************************')

print('使用深拷贝:')
a = ['A', 'B', ['C', 'D', 'E'], 'F']
# 使用深拷贝
b = copy.deepcopy(a)
b[2][1] = 42
print(id(a), a)
print(id(b), b)

运行结果:

使用浅拷贝:
4461652240 ['A', 'B', ['C', 42, 'E'], 'F']
4461651680 ['A', 'B', ['C', 42, 'E'], 'F']
*********************************************
使用深拷贝:
4461652000 ['A', 'B', ['C', 'D', 'E'], 'F']
4461652240 ['A', 'B', ['C', 42, 'E'], 'F']

由此可见:

如果列表或者字典没有包含子列表或者子字典的话,使用深拷贝或者浅拷贝效果都有一样;

如果列表或者字典中存在子类的时候,只有深拷贝才会为所有的子类也重新分配内存,而浅拷贝只负责父对象,不考虑子对象。

(原贴:https://cloud.tencent.com/developer/article/1597913)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值