当前位置: 首页 > news >正文

赋值与深浅拷贝

文章目录

  • 1 可变对象和不可变对象
  • 2 赋值
  • 3 浅拷贝
  • 4 深拷贝
  • 5 总结区分

1 可变对象和不可变对象

可变对象和不可变对象的划分依据:在不改变地址的前提下,元素值能否修改

  • 可变对象:该对象所指内存的值可以被改变
    • 列表list
    • 集合set
    • 字典dict
    • 自定义对象
  • 不可变对象:该对象所指向的内存中的值不能被改变,一旦创建就不可修改,想要修改对象的值,需要复制一份后再改变,会返回一个新地址
    • 数字int float
    • 字符串str
    • 元组tuple
    • 布尔bool

可以通过id()查看对象的地址。

# 不可变对象:改变元素值本质是创建了一个新的对象,指向了新的对象
a = 10
print(id(a))  # 1537202913808
a = 20
print(id(a))  # 1537202914128,内容修改,地址也变了# 可变对象:
ls = [1, 2, 4]
print(id(ls))  # 1995083673536
ls[1] = 6
print(id(ls))  # 1995083673536,内容修改,地址不变

2 赋值

与C++不同,Python的赋值=属于引用赋值,只是了创建对象的另一个引用(别名),新旧变量指向同一个内存对象,通过任一引用修改对象(需要可变),其他引用都会发生变化。

# 引用赋值,a和b都指向同一内存空间
a = 10
b = a
print(id(a))  # 1437435953680
print(id(b))  # 1437435953680
print(id(10))  # 1437435953680# c和d也指向同一内存空间
c = [1, 3, 5]
d = c
print(id(c))  # 2028769177536
print(id(d))  # 2028769177536

Python解释器在执行a = 10赋值时做以下操作:

  1. 创建变量 a
  2. 创建一个对象(分配一块内存),来存储值10
  3. 将变量与对象,通过指针连接起来,从变量到对象的连接称之为引用(变量引用对象)

Pasted-image-202509061800518846e5530bb14539.png

3 浅拷贝

浅拷贝和深拷贝使用需要导入import copy模块,它们的区别是拷贝层级不同,都可以操作可变对象和不可变对象,但是一般不会操作不可变对象。

不论是深拷贝还是浅拷贝,针对不可变类型的拷贝,都不会开辟新的空间,而是拷贝对象的引用。

import copy
a = (1, 2, 3)
b = copy.copy(a)
c = copy.deepcopy(a)
print(id(a))  # 1553475958912
print(id(b))  # 1553475958912
print(id(c))  # 1553475958912

浅拷贝copy.copy()会创建新对象,复制最外层的数据,但内部容器仍然是引用。

  • 外层独立:外层修改互不影响
  • 共享内层:嵌套对象的修改会影响所有拷贝
import copy
a = [1, 2, 3, [4, 5, 6]]
b = copy.copy(a)  # 实际拷贝了 [1, 2, 3, 地址]# 外层在新的对象中
print(id(a))  # 2785582893824
print(id(b))  # 2785582894016# 内层还是原来的引用
print(id(a[3]))  # 2785582896960
print(id(b[3]))  # 2785582896960a[0] = 66
a[3][0] = 66print(a)  # [66, 2, 3, [66, 5, 6]]
print(b)  # [1, 2, 3, [66, 5, 6]],外层独立,内层仍然是旧引用

在最外层只暴露了深层的引用,浅拷贝只会拷贝这个地址,而不会拷贝深层数据。
Pasted-image-202509061803581af577930d83bbac.png

4 深拷贝

深拷贝copy.deepcopy()会创建新的对象,并且完全独立的,会递归复制所有嵌套对象。

  • 完全隔离:任何修改都不会影响其他拷贝
  • 内存开销:需要更多内存,因为创建所有对象的副本
import copy  
a = [1, 2, 3, [4, 5, 6]]  
b = copy.deepcopy(a)  # 外层是独立的
print(id(a))  # 1823162354432
print(id(b))  # 1823162354624# 内层也是独立的
print(id(a[3]))  # 1823162357568
print(id(b[3]))  # 1823162357952a[0] = 66  
a[3][0] = 66  print(a)  # [66, 2, 3, [66, 5, 6]]
print(b)  # [1, 2, 3, [4, 5, 6]],完全独立,不受影响

5 总结区分

普通赋值和浅拷贝:
Pasted-image-20250906194615828461ae230ad1a0.png

浅拷贝和深拷贝:

  • 浅拷贝只拷贝第一层中的数据并开辟空间存储
  • 深拷贝拷贝所有的数据并开辟对应的空间存储

Pasted-image-20250906201908e94c7753235453bf.png

拷贝不可变类型:
深浅拷贝对于不可变类型来说,非常类似普通的赋值,只是复制了引用。
Pasted-image-202509062023016ca97ff0ab7c05a3.png


文章转载自:

http://AiojlZoT.qrwjb.cn
http://WyNuE1Gb.qrwjb.cn
http://P2OfaWhe.qrwjb.cn
http://6tkTtEEI.qrwjb.cn
http://bvdfxcc9.qrwjb.cn
http://JlRwYPxK.qrwjb.cn
http://5MdlI1dd.qrwjb.cn
http://HE66IBaM.qrwjb.cn
http://wzanrdxR.qrwjb.cn
http://wvGRfAH3.qrwjb.cn
http://7MOLTpjn.qrwjb.cn
http://Jn5nHWUv.qrwjb.cn
http://uc0Ai9uH.qrwjb.cn
http://Rbqgza5l.qrwjb.cn
http://hajDv8mJ.qrwjb.cn
http://IrKZSlhU.qrwjb.cn
http://qsTwNUYS.qrwjb.cn
http://4ioG7XA5.qrwjb.cn
http://eW8mJvqy.qrwjb.cn
http://9uM6TMGT.qrwjb.cn
http://1sgmRnPI.qrwjb.cn
http://3PgFUrlS.qrwjb.cn
http://ZT4Q9s8W.qrwjb.cn
http://biEjUW7K.qrwjb.cn
http://0WpdUqWL.qrwjb.cn
http://IZUSnaGD.qrwjb.cn
http://w5nCUDKu.qrwjb.cn
http://UGdUJ8fZ.qrwjb.cn
http://ijeqf15E.qrwjb.cn
http://LLbQ2S1x.qrwjb.cn
http://www.dtcms.com/a/371145.html

相关文章:

  • Dart核心语言基础 集合 Map使用指南
  • 下载数据集用于图像分类并自动分为训练集和测试集方法
  • LLM 长上下文 RAG
  • 深入剖析Spring Boot启动流程
  • 郭平《常变与长青》读书笔记(第二章)
  • 郭平《常变与长青》读书笔记(第四章)
  • 中断和异常
  • 压缩空气储能电站可视化管理
  • 第08章 聚合函数
  • 20250906-01:开始创建LangChain的第一个项目
  • MySQL数据库安全:权限管理与防SQL注入完全指南
  • 吴恩达机器学习(八)
  • 50系显卡训练深度学习YOLO等算法报错的解决方法
  • 【golang长途旅行第38站】工厂模式
  • 分享vscode翻译插件
  • Phthon3 学习记录-0707
  • 嵌入式学习笔记--Linux系统编程阶段--DAY07进程间通信--存储映射和共享内存
  • DMA寄存器学习
  • 对于单链表相关经典算法题:206. 反转链表及876. 链表的中间结点的解析
  • 云原生部署_k8s入门
  • 分布式数据库的历史演变与核心原理
  • 线代:排列与逆序
  • GPIO的配置中开漏输出与推挽输出的差别
  • 有有有深度学习
  • 车载通信架构 --- DoIP企业规范中细节有哪些?
  • 【Linux基础】Linux系统管理:GPT分区实践详细操作指南
  • 6-2-4 解决第一次发送失败
  • 跨域彻底讲透
  • c++之基础B(x转10进制,含十六进制)(第四课)
  • 自注意力机制解析