【Python基础知识点】Python的浅拷贝和深拷贝

news/2024/12/23 0:42:33/

概述

本文主要通过两个简单的代码小例子理解深拷贝和浅拷贝

主体内容

copy 模块提供了浅拷贝和深拷贝的功能。它的主要函数有:
copy(x): 返回对象 x 的浅拷贝。
deepcopy(x): 返回对象 x 的深拷贝。
浅拷贝使用 copy(x) 函数,它只复制了最外层的对象,但内层的对象仍然是引用。此外当我们使用切片操作 [:]、工厂函数如 list() copy模块时,也是使用的浅拷贝,尽管我们创建了一个新的对象,它有自己的内存空间。但是,如果原始对象包含其他对象的引用(如列表中的列表,字典中的列表等),那么新对象和原始对象将共享这些内层对象的同一引用。

让我们通过一个例子来理解这一点:

original_list = [1, 2, [3, 4]]
new_list = original_list[:]  # 使用切片操作进行浅拷贝print(original_list)  # 输出: [1, 2, [3, 4]]
print(new_list)       # 输出: [1, 2, [3, 4]]# 修改原始列表的第一个元素
original_list[0] = 100
print(original_list)  # 输出: [100, 2, [3, 4]]
print(new_list)       # 输出: [1, 2, [3, 4]]# 修改原始列表中内层列表的第一个元素
original_list[2][0] = 300
print(original_list)  # 输出: [100, 2, [300, 4]]
print(new_list)       # 输出: [1, 2, [300, 4]]

在这个例子中:

我们首先创建了一个列表 original_list,其中包含两个整数和一个内层列表。

我们使用切片操作 [:] 创建了 original_list 的浅拷贝 new_list

然后我们修改original_list 的第一个元素。我们发现 new_list 没有受到影响,因为它是一个独立的对象。

但是,当我们修改 original_list 中内层列表的第一个元素时,我们发现 new_list 中的内层列表也被修改了。这是因为 new_listoriginal_list 共享了内层列表的同一引用。

所以,浅拷贝创建了一个新的对象,但如果原始对象包含其他对象的引用,那么新对象和原始对象将共享这些引用。对原始对象的外层修改不会影响新对象,但对内层对象的修改会影响新对象,因为它们共享同一引用。

如果你想创建一个完全独立的副本,包括内层对象,你需要使用深拷贝(deep copy)。在 Python 中,你可以使用copy模块的deepcopy()函数来创建深拷贝。

深拷贝使用 deepcopy(x) 函数,它创建一个新的复合对象,然后递归地插入原始对象中的对象的副本。这意味着深拷贝也复制了内层对象,深拷贝才是真正意义上我们理解的复制,全须全尾地开辟了一个内存空间复制了一遍。

import copyoriginal_list = [1, 2, [3, 4]]
new_list = copy.deepcopy(original_list)  # 使用 deepcopy() 函数进行深拷贝print(original_list)  # 输出: [1, 2, [3, 4]]
print(new_list)       # 输出: [1, 2, [3, 4]]# 修改原始列表的第一个元素
original_list[0] = 100
print(original_list)  # 输出: [100, 2, [3, 4]]
print(new_list)       # 输出: [1, 2, [3, 4]]# 修改原始列表中内层列表的第一个元素
original_list[2][0] = 300
print(original_list)  # 输出: [100, 2, [300, 4]]
print(new_list)       # 输出: [1, 2, [3, 4]]

一句话总结

在大多数情况下,如果你的对象只包含原始数据类型只有一层嵌套,你可以使用浅拷贝。但如果你的对象包含多层嵌套或可变对象,为了确保完全的独立性,你应该使用深拷贝


http://www.ppmy.cn/news/1405436.html

相关文章

EfficientVMamba实战:使用EfficientVMamba实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构编译安装Vim环境环境安装过程安装库文件 计算mean和std生成数据集 摘要 论文:https://arxiv.org/pdf/2401.09417v1.pdf 作者研究了轻量级模型设计的新方法,通过引入视觉状态空间模型&…

YOLOv5改进系列:升级版ResNet的新主干网络DenseNet

一、论文理论 论文地址:Densely Connected Convolutional Networks 1.理论思想 DenseNet最大化前后层信息交流,通过建立前面所有层与后面层的密集连接,实现了特征在通道维度上的复用,不但减缓了梯度消失的现象,也使其…

AI2.0时代如何快速落地AI智能应用开发,抓住时代机会

写在前面的话 当我们提到人工智能时也就是AI的时候呢,我们大多数人首先想到的可能就是像chatGPT这样的聊天机器人,这些聊天机器人通过理解,还有生成自然语言可以给我们提供一些信息,这个是AI最终的形态吗或者AI最终的形式吗&…

每日三个JAVA经典面试题(三十四)

1.Mybatis的一级、二级缓存 MyBatis提供了两种缓存机制来提高查询效率:一级缓存和二级缓存。 一级缓存(Session级别) 作用范围:一级缓存是基于SqlSession的。这意味着,如果你在同一个SqlSession中执行两次相同的查询…

数据可视化之折线图plot

import matplotlib.pyplot as plt plt.rcParams[font.family] [SimHei]# 查看matplotlibde文件地址# import matplotlib # print(matplotlib.matplotlib_fname()) # plt.rcParams[font.sans-serif] [SimHei] # 准备数据time [20200401,20200402,20200403,20200404,20200405…

nginx与tomcat的区别?

关于nginx和tomcat的概念 网上有很多关于nginx和tomcat是什么东西的定义,我总结了一下: tomcat是Web服务器、HTTP服务器、应用服务器、Servlet容器、web容器。 Nginx是Web服务器、HTTP服务器、正向/反向代理服务器,。 这里有两个概念是交叉的&#xff…

Springboot自动获取接口实现

ServiceLoader加载接口实现步骤 1.编写接口 public interface CommunicationAdapterFactory {void setKernel(LocalKernel kernel);boolean providesAdapterFor(Vehicle vehicle);BasicCommunicationAdapter getAdapterFor(Vehicle vehicle); }2.编写实现 // 实现类 1 publi…

ElasticSearch的常用数据类型

常见的数据类型 Text类型(文本数据类型) 用于索引全文值的字段,例如电子邮件的正文或产品的描述。这些字段是analyzed,也就是说,它们通过分析器传递,以便 在被索引之前将字符串转换为单个术语的列表。通过…