深拷贝和浅拷贝

深拷贝和浅拷贝

# 导入copy模块
import copy

浅拷贝

  • copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象的子对象。

不可变类型的浅拷贝说明:

  • 不可变类型进行浅拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用
import copy  # 使用浅拷贝需要导入copy模块
# 不可变类型有: 数字、字符串、元组
# 数字
a1 = 123123
b1 = copy.copy(a1)  # 使用copy模块里的copy()函数就是浅拷贝了
print(id(a1))  # 140459558944048
print(id(b1))  # 140459558944048

# 字符串
a2 = "abc"
b2 = copy.copy(a2)
print(id(a2))  # 140459558648776
print(id(b2))  # 140459558648776

# 元组
a3 = (1, 2, ["hello", "world"])
b3 = copy.copy(a3)
print(id(a3))  # 140459558648776
print(id(b3))  # 140459558648776

a3[2][1] = "hello"
print(a3[2])  # ['hello', 'hello']
print(b3[2])  # ['hello', 'hello']

可变类型的浅拷贝说明:

  • 可变类型进行浅拷贝只对可变类型的第一层对象进行拷贝,对拷贝的对象会开辟新的空间进行存储,子对象不进行拷贝
import copy
# 可变类型有: 列表、字典、集合
# 列表
a1 = [1, 2]
b1 = copy.copy(a1)  # 使用copy模块里的copy()函数就是浅拷贝了
print(id(a1))  # 139882899585608
print(id(b1))  # 139882899585800

# 字典
a2 = {"name": "张三", "age": 20}
b2 = copy.copy(a2)
print(id(a2))  # 139882919626432
print(id(b2))  # 139882919626504

# 集合
a3 = {1, 2, "王五"}
b3 = copy.copy(a3)
print(id(a3))  # 139882919321672
print(id(b3))  # 139882899616264

# 列表
a4 = [1, 2, [4, 5]]
# 注意:浅拷贝只会拷贝父对象,不会对子对象进行拷贝
b4 = copy.copy(a4)  # 使用copy模块里的copy()函数就是浅拷贝了
print(id(a4))  # 139882899587016
print(id(b4))  # 139882899586952
print(id(a4[2]))  # 139882899693640
print(id(b4[2]))  # 139882899693640

# 修改数据
a4[2][0] = 6

# 子对象的数据会受影响
print(a4)  // [1, 2, [6, 5]]
print(b4)  // [1, 2, [6, 5]]
  • 注意集合对象.copy()方法和列表的切片[:]都是浅拷贝。

深拷贝

  • deepcopy函数是深拷贝,只要发现对象有可变类型就会对该对象到最后一个可变类型的每一层对象进行拷贝,对每一层拷贝的对象都会开辟新的内存空间进行存储。

不可变类型的深拷贝说明:

  • 不可变类型进行深拷贝如果子对象没有可变类型则不会进行拷贝,而只是拷贝了这个对象的引用。遇到不可变类型里套可变类型,子对象按可变类型进行深拷贝。
import copy 

# 数字
a1 = 1
b1 = copy.deepcopy(a1)  # 使用copy模块里的deepcopy()函数就是深拷贝了
print(id(a1)) # 9289120
print(id(b1))  # 9289120

# 字符串
a2 = "张三"
b2 = copy.deepcopy(a2)
print(id(a2))  # 140115621848320
print(id(b2))  # 140115621848320

# 元组
a3 = (1, 2)
b3 = copy.deepcopy(a3)
print(id(a3))  # 140115621859592
print(id(b3))  # 140115621859592

# 注意: 元组里面要是有可变类型对象,
# 发现对象有可变类型就会该对象到最后一个可变类型的每一层对象进行拷贝
a4 = (1, ["李四"])
b4 = copy.deepcopy(a4)
print(id(a4))  # 140115602480584
print(id(b4))  # 140115621834568
# 元组里面的可变类型子对象也会进行拷贝
print(id(a4[1]))  # 140115602328136
print(id(b4[1]))  # 140115602436168

可变类型的拷贝说明:

  • 可变类型进行深拷贝会对该对象到最后一个可变类型的每一层对象进行拷贝,对每一层拷贝的对象都会开辟新的内存空间进行存储。
import copy 

# 列表
a1 = [1, 2]
b1 = copy.deepcopy(a1) 
print(id(a1))  # 140348291721736
print(id(b1))  # 140348291721928

# 字典
a2 = {"name": "张三"}
b2 = copy.deepcopy(a2)
print(id(a2))  # 140348311762624
print(id(b2))  # 140348311221592

# 集合
a3 = {1, 2}
b3 = copy.deepcopy(a3)
print(id(a3))  # 140348311457864
print(id(b3))  # 140348291752456

# 列表
a4 = [1, 2, ["李四", "王五"]]
b4 = copy.deepcopy(a4) 
print(id(a4))  # 140348291723080
print(id(b4))  # 140348291723144
print(id(a4[2]))  # 140348291723208
print(id(b4[2]))  # 140348291723016

a4[2][0] = "王五"
# 因为列表的内存地址不同,所以数据不会收到影响
print(a4)  // [1, 2, ['王五', '王五']]
print(b4)  // [1, 2, ['李四', '王五']]

深拷贝和浅拷贝的区别

  1. 浅拷贝最多拷贝对象的一层
  2. 深拷贝可以拷贝对象的多层
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼义虎神

打赏5C币,作者可获得4C币

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值