Python - 对象赋值、浅拷贝、深拷贝的区别(下)

简介: Python - 对象赋值、浅拷贝、深拷贝的区别(下)

那为什么要深拷贝呢?


修改列表内的不可变对象元素

上面的栗子是直接添加元素,来看看修改元素会怎么样

# 不可变元素
import copy
old_list = [1, 2, "string", (1, 2,)]
new_list = copy.copy(old_list)
old_list[1] += 22
old_list[2] += "s"
old_list[3] += (3,)
print("Old list:", old_list)
print("New list:", new_list)
# 输出结果
Old list: [1, 24, 'strings', (1, 2, 3)]
New list: [1, 2, 'string', (1, 2)]


修改 old_list 的三种不可变对象元素,均不会同步给 new_list

 

修改不可变对象的原理图

image.png


修改列表内的可变对象元素

# 可变元素
import copy
old_list = [[1, 2], [3, 4]]
new_list = copy.copy(old_list)
old_list[0][0] += 99
old_list[1][0] += 97
print("Old list:", old_list, "old list id:", id(old_list), " old list[0] id:", id(old_list[0]))
print("new list:", new_list, "new list id:", id(new_list), " new list[0] id:", id(new_list[0]))
# 输出结果
Old list: [[100, 2], [100, 4]] old list id: 4430308096  old list[0] id: 4430302400
new list: [[100, 2], [100, 4]] new list id: 4430308416  new list[0] id: 4430302400


从输出结果看到

  • 两个变量保存了不同的对象引用
  • 但是可变对象元素的内存地址仍然是同一个

 

修改可变对象的原理图


image.png


总结

  • 修改可变对象是在原始对象上直接操作的
  • 浅拷贝产生的新对象存储的仍然是原始对象的内存地址
  • 所以修改可变对象的时候,新对象的值也会被同步修改,因为新旧列表对象的元素的引用是指向同一个内存地址
  • 当修改可变对象的时候,不满足一开始说的实际应用场景,所以诞生了深拷贝

 

深拷贝


  • 创建一个新对象,且存储的对象引用也是新的
  • 深,意味着会把所有子元素对象也复制生成一个新对象

 

栗子一

# 深拷贝
old_list = [[1, 2], [3, 4]]
new_list = copy.deepcopy(old_list)
old_list[0][0] += 99
old_list[1][0] += 97
print("Old list:", old_list, "old list id:", id(old_list), " old list[0] id:", id(old_list[0]))
print("new list:", new_list, "new list id:", id(new_list), " new list[0] id:", id(new_list[0]))
# 输出结果
Old list: [[100, 2], [100, 4]] old list id: 4430308480  old list[0] id: 4430211392
new list: [[1, 2], [3, 4]] new list id: 4430308096  new list[0] id: 4430308864


从输出结果看到

  • 两个变量保存了不同的对象引用
  • 可变对象元素(子对象)的内存地址也是不同的

 

栗子二

假设是一个三维列表呢

# 深拷贝-三维数组
old_list = [[1, [10, 9]], [3, 4]]
new_list = copy.deepcopy(old_list)
old_list[0][1][0] += 90
print("Old list:", old_list)
print("New list:", new_list)
# 输出结果
Old list: [[1, [100, 9]], [3, 4]]
New list: [[1, [10, 9]], [3, 4]]


两个变量依旧是独立的

 

深拷贝原理图

image.png

浅拷贝的多种实现方式


https://www.cnblogs.com/poloyy/p/15086511.html

 

面试题:浅拷贝、深拷贝的区别


  1. 浅拷贝和深拷贝只有在可变对象才会生效,不可变对象的赋值操作、浅拷贝、深拷贝的效果是一样的
  2. 浅拷贝会将对象复制生成一个新对象,但新对象仍然存储原始对象的引用,当原始对象是可变对象,然后修改它的值时,新旧对象会同时改变
  3. 深拷贝不仅会将对象复制生成一个新对象,且所有原始对象都会复制生成新对象,即使原始对象是可变对象,新对象存储的对象引用也是新的,所以改变旧对象的可变对象时,不会影响新对象


相关文章
|
27天前
|
存储 开发者 Python
Python 中的数据结构与其他编程语言数据结构的区别
不同编程语言都有其设计理念和应用场景,开发者需要根据具体需求和语言特点来选择合适的数据结构
|
8天前
|
存储 数据处理 Python
Python如何显示对象的某个属性的所有值
本文介绍了如何在Python中使用`getattr`和`hasattr`函数来访问和检查对象的属性。通过这些工具,可以轻松遍历对象列表并提取特定属性的所有值,适用于数据处理和分析任务。示例包括获取对象列表中所有书籍的作者和检查动物对象的名称属性。
19 2
|
22天前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
31 3
|
2月前
|
存储 大数据 数据处理
Python 中的列表推导式与生成器:特性、用途与区别
Python 中的列表推导式与生成器:特性、用途与区别
34 2
|
2月前
|
机器学习/深度学习 缓存 Linux
python环境学习:pip介绍,pip 和 conda的区别和联系。哪个更好使用?pip创建虚拟环境并解释venv模块,pip的常用命令,conda的常用命令。
本文介绍了Python的包管理工具pip和环境管理器conda的区别与联系。pip主要用于安装和管理Python包,而conda不仅管理Python包,还能管理其他语言的包,并提供强大的环境管理功能。文章还讨论了pip创建虚拟环境的方法,以及pip和conda的常用命令。作者推荐使用conda安装科学计算和数据分析包,而pip则用于安装无法通过conda获取的包。
153 0
|
C# Python
Python中的module,library,package之间的区别
背景 Python中有一些基本的名词,很多人,尤其是一些初学者,可能听着就很晕。 此处,简单总结一下,module,library,package之间的大概区别。 Python中的module的简介 module,中文翻译为:模块 Python中的module,说白了,就是Python文件,而python文件一般后缀为py,所以就是你的xxx.py而已。
1740 0
|
22天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
20天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
9天前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
101 80
|
27天前
|
存储 索引 Python
Python编程数据结构的深入理解
深入理解 Python 中的数据结构是提高编程能力的重要途径。通过合理选择和使用数据结构,可以提高程序的效率和质量
134 59