QA测试开发工程师面试题满分问答3: python的深拷贝和浅拷贝问题

在 Python 中,深拷贝(deep copy)和浅拷贝(shallow copy)是用于创建对象副本的两种不同方式。

  • 浅拷贝是创建一个新的对象,该对象与原始对象的内容相同(包括内部嵌套对象的引用),但是它们指向相同的内存地址。换句话说,浅拷贝创建了一个对象的表面副本,而不是递归复制所有嵌套对象。当原始对象包含可变对象(如列表、字典)时,对副本进行修改可能会影响原始对象。
  • 深拷贝是创建一个全新的对象,该对象与原始对象内容相同,包括所有嵌套对象。深拷贝递归地复制所有嵌套对象,而不仅仅是创建一个表面副本。因此,对深拷贝对象的修改不会影响原始对象。

下面是深拷贝和浅拷贝的用途:

  1. 浅拷贝适用于需要创建一个对象的快速副本,但不需要对副本进行深层次的修改。它可以节省内存和复制时间,特别是当对象包含大量数据或嵌套对象时。
  2. 深拷贝适用于需要创建一个完全独立的对象,以便对副本进行修改而不会影响原始对象。它用于确保对象及其所有嵌套对象在修改时的独立性。

在 Python 中,可以使用 copy 模块来执行深拷贝和浅拷贝操作。以下是示例代码:

import copy# 浅拷贝示例
original_list = [1, 2, [3, 4]]
shallow_copy = copy.copy(original_list)# 修改浅拷贝对象的嵌套列表
shallow_copy[2][0] = 5print(original_list)  # 输出: [1, 2, [5, 4]]
print(shallow_copy)  # 输出: [1, 2, [5, 4]]# 深拷贝示例
deep_copy = copy.deepcopy(original_list)# 修改深拷贝对象的嵌套列表
deep_copy[2][1] = 6print(original_list)  # 输出: [1, 2, [5, 4]]
print(deep_copy)  # 输出: [1, 2, [5, 6]]

在上述示例中,我们首先对一个包含嵌套列表的原始列表进行浅拷贝和深拷贝操作。然后,修改拷贝后的对象的嵌套列表的值。可以看到,浅拷贝对象的嵌套列表修改也影响了原始列表,而深拷贝对象的修改不会影响原始列表。

可能遇到的问题

在进行深拷贝和浅拷贝时,可能会遇到以下问题:

  1. 嵌套对象的共享引用:浅拷贝只复制了对象的引用,而不是创建嵌套对象的副本。这意味着如果对浅拷贝对象中的嵌套对象进行修改,原始对象也会受到影响。这可能导致意外的副作用。

  2. 无限递归:如果存在循环引用或互相引用的对象,进行深拷贝时可能会导致无限递归。这会导致程序进入无限循环并最终引发 "RecursionError" 异常。

  3. 可变对象的修改:无论是深拷贝还是浅拷贝,如果复制的对象包含可变对象(如列表或字典),对副本进行修改可能会影响原始对象。这是因为副本和原始对象引用同一个可变对象。

  4. 性能和内存消耗:深拷贝涉及递归地复制所有嵌套对象,这可能对性能和内存消耗产生一定影响,特别是在处理大型对象或嵌套层次较深的对象时。

一个重要问题:嵌套列表内的引用是相同的

当进行浅拷贝时,新创建的列表中的元素是原始列表中元素的引用,而不是元素的副本。这意味着如果在浅拷贝列表中的嵌套列表上进行修改,原始列表中相应的嵌套列表也会受到影响。

通过一个示例来说明这个问题:

import copyoriginal_list = [1, [2, 3], 4]
shallow_copy = copy.copy(original_list)# 修改浅拷贝列表中的嵌套列表
shallow_copy[1].append(5)print(original_list)  # 输出: [1, [2, 3, 5], 4]
print(shallow_copy)  # 输出: [1, [2, 3, 5], 4]

在上述示例中,我们对一个包含嵌套列表的原始列表进行浅拷贝。然后,我们修改浅拷贝列表中的嵌套列表,结果原始列表中的嵌套列表也被修改了。

这是因为浅拷贝只复制了嵌套列表的引用,而不是创建嵌套列表的副本。因此,对浅拷贝列表中的嵌套列表进行修改实际上是对原始列表中相应的嵌套列表进行修改。

要解决这个问题,你可以使用深拷贝来创建所有嵌套列表的副本,而不是共享引用。这样,对深拷贝列表中的嵌套列表进行修改不会影响原始列表。

import copyoriginal_list = [1, [2, 3], 4]
deep_copy = copy.deepcopy(original_list)# 修改深拷贝列表中的嵌套列表
deep_copy[1].append(5)print(original_list)  # 输出: [1, [2, 3], 4]
print(deep_copy)  # 输出: [1, [2, 3, 5], 4]

在上述示例中,我们使用深拷贝创建了嵌套列表的副本。对深拷贝列表中的嵌套列表进行修改不会影响原始列表。

因此,当涉及到嵌套列表时,特别是在进行拷贝操作时,请考虑使用深拷贝来确保所有嵌套列表的副本都被创建,以避免意外行为

当涉及到嵌套字典时,浅拷贝也会导致类似的问题。通过一个例子来说明:

import copyoriginal_dict = {'a': 1, 'b': {'x': 2, 'y': 3}}
shallow_copy = copy.copy(original_dict)# 修改浅拷贝字典中的嵌套字典
shallow_copy['b']['x'] = 4print(original_dict)  # 输出: {'a': 1, 'b': {'x': 4, 'y': 3}}
print(shallow_copy)  # 输出: {'a': 1, 'b': {'x': 4, 'y': 3}}

在上述示例中,我们对一个包含嵌套字典的原始字典进行浅拷贝。然后,我们修改浅拷贝字典中的嵌套字典的值,结果原始字典中相应的嵌套字典也被修改了。

这是因为浅拷贝只复制了嵌套字典的引用,而不是创建嵌套字典的副本。因此,对浅拷贝字典中的嵌套字典进行修改实际上是对原始字典中相应的嵌套字典进行修改。

同样地,为了解决这个问题,你可以使用深拷贝来创建所有嵌套字典的副本,而不是共享引用。这样,对深拷贝字典中的嵌套字典进行修改不会影响原始字典。

import copyoriginal_dict = {'a': 1, 'b': {'x': 2, 'y': 3}}
deep_copy = copy.deepcopy(original_dict)# 修改深拷贝字典中的嵌套字典
deep_copy['b']['x'] = 4print(original_dict)  # 输出: {'a': 1, 'b': {'x': 2, 'y': 3}}
print(deep_copy)  # 输出: {'a': 1, 'b': {'x': 4, 'y': 3}}

在上述示例中,我们使用深拷贝创建了嵌套字典的副本。对深拷贝字典中的嵌套字典进行修改不会影响原始字典。

因此,无论是嵌套列表还是嵌套字典,在进行拷贝操作时,请考虑使用深拷贝来确保所有嵌套对象的副本都被创建,以避免意外修改原始对象的问题

    三段头部互联网大厂测开经历,辅导过25+同学入职大厂,【简历优化】、【就业指导】、【模拟/辅导面试】一对一指导

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Higress 基于自定义插件访问 Redis

作者:钰诚 简介 基于 wasm 机制,Higress 提供了优秀的可扩展性,用户可以基于 Go/C/Rust 编写 wasm 插件,自定义请求处理逻辑,满足用户的个性化需求,目前插件已经支持 redis 调用,使得用户能够…

LeetCode刷题:无重复字符的最长子串 详解 【3/1000 第三题】

👤作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。 会一些的技术:数据分析、算法、SQL、大数据相关、python 作者专栏每日更新: LeetCode解锁1000题: 打怪升级之旅 LeetCode解锁1000题: 打怪升级之旅htt…

【THM】Active Reconnaissance(主动侦察)-初级渗透测试

介绍 在网络安全模块的第一个房间里,我们主要进行被动侦察。在第二个房间中,我们重点关注主动侦察以及与之相关的基本工具。我们学习使用网络浏览器来收集有关我们目标的更多信息。此外,我们讨论使用简单的工具(例如ping、traceroute、telnet和 )nc来收集有关网络、系统和…

探讨在大数据体系中API的通信机制与工作原理

** 引言 关联阅读博客文章:深入解析大数据体系中的ETL工作原理及常见组件 关联阅读博客文章:深入理解HDFS工作原理:大数据存储和容错性机制解析 ** 在当今数字化时代,数据已经成为企业发展和决策的核心。随着数据规模的不断增长…

计算机组成原理实验(汉字编码实验)

(汉字编码实验) 海明校验码实验

每天五分钟计算机视觉:如何基于滑动窗口技术完成目标的检测?

汽车检测算法 现在我们想要构建一个汽车检测算法,我们希望输入到算法中一张图片,算法就可以帮助我们检测出这张图片中是否有汽车。 数据集 首先创建一个标签训练集,x是样本,y是标签。我们的训练集最好是被剪切过的图片,剪掉汽车以外的部分,使汽车居于中间位置,就是整张…

LeetCode-240. 搜索二维矩阵 II【数组 二分查找 分治 矩阵】

LeetCode-240. 搜索二维矩阵 II【数组 二分查找 分治 矩阵】 题目描述:解题思路一:从左下角或者右上角元素出发,来寻找target。解题思路二:右上角元素,代码解题思路三:暴力也能过解题思路四:二分…

家庭网络防御系统搭建-配置流量镜像到NDR系统

由于需要将家庭网络中的全部流量送到NDR分析系统进行分析,因此需要一个具备流量镜像功能的交换机或者路由器。在前面文章所提及的家庭网络架构中,需要一台交换机即可拷贝东西向流量以及南北向流量。当然如果家庭中的路由器或者其他设备具备交换机镜像功能…

基于单片机智能数字温度采集报警器系统设计

**单片机设计介绍,基于单片机智能数字温度采集报警器系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机智能数字温度采集报警器系统设计的核心目标是通过单片机实现温度的实时采集、显示以及超温报警…

深度学习_NLP常用库报错问题解决

1、SpaCy can‘t find model ‘zh_core_web_sm‘. It doesn‘t seem to be a python package or a valid path to a data 或者 can‘t find model ‘en_core_web_sm‘. It doesn‘t seem to be a python package or a valid path to a data 安装最新的版本: en_…

C++项目——集群聊天服务器项目(七)Model层设计、注册业务实现

在前几节的研究中,我们已经实现网络层与业务层分离,本节实现数据层与业务层分离,降低各层之间的耦合性,同时实现用户注册业务。 网络层专注于处理网络通信与读写事件 业务层专注于处理读写事件到来时所需求的各项业务 数据层专…

UE5 SQLite笔记

开发环境: 系统:Windows 10 64 bit 引擎:Unreal Engine 5.1.1 IDE:JetBrains Rider 2023.2.1 语言:C 工具:DB Browser for SQLite SQLite数据类型: //INTEGER TEXT BLOB REAL NUMERIC/*integer…

关于OpenFeign的返回类型包装问题

在一天夜里。我在使用feign的调用时,突然出现了一点点问题。 就是对于feign类型的包装问题。产生了疑问。 在后来,也就是今天。在网上取取经。看到了一个答案。说:feign的调用会有一个编码器和解码器。 使用feign的解码器。他的原理也很简…

NoSQL之Redis配置

文章目录 NoSQL之Redis配置一、关系数据库和非关系数据库1、关系型数据库2、非关系型数据库3、非关系型数据库产生背景4、关系型数据库和非关系型数据库的区别4.1 数据存储方式不同4.2 扩展方式不同4.3 对事务性的支持不同 5、总结5.1 关系型数据库5.2 非关系型数据库 二、Redi…

基于springboot实现房屋租赁管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现房屋租赁系统演示 摘要 房屋是人类生活栖息的重要场所,随着城市中的流动人口的增多,人们对房屋租赁需求越来越高,为满足用户查询房屋、预约看房、房屋租赁的需求,特开发了本基于Spring Boot的房屋租赁系统。 …

鸿蒙实战开发-如何使用三方库

使用三方库 在使用三方库之前,需要安装 ohpm,并在环境变量中配置。 在项目目录的Terminal窗口执行ohpm命令下载依赖 ohpm install yunkss/eftool 命令运行成功后,在项目的oh-package.json5文件中会自动添加上依赖,如下所示&am…

JimuReport积木报表 v1.7.4 正式版本发布,免费的JAVA报表工具

项目介绍 一款免费的数据可视化报表,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等! Web 版报表设计器,类似于excel操作风格,通过拖拽完成报…

Qt加载.css/.qss文件设置控件的QSS样式(支持程序运行时修改且立即生效类似换肤效果)

初学Qt时,你是如何设置QWidget,QPushButton等原生基础控件的样式的?是不是主要是两种方法? 1.直接在可视化的.ui文件中直接添加qss语句。 2.在代码中通过setStyleSheet(QString qss)来设置qss语句。 上述两种方法,在程…

【数据结构】你知道波兰表达式和逆波兰表达式吗?我才知道原来栈在表达式求值中还能这样使用……

栈在表达式求值中的应用 导读一、表达式的形式二、波兰表达式与逆波兰表达式三、表达式之间的相互转换四、栈实现波兰表达式4.1 问题分析4.2 问题完善4.3 算法实现4.3.1 获取波兰表达式4.3.2 从右往左扫描表达式4.3.3 遇到操作数进行入栈操作4.3.4 遇到操作符进行对应操作4.3.5…

Qt元对象系统

第二章Qt元对象系统 文章目录 第二章Qt元对象系统1.什么是元对象?2.元对象系统组成3.信号与槽信号和槽的本质绑定信号与槽自定义槽定义槽函数必须遵循一下规则槽函数的类型自定义槽案例 自定义信号自定义信号需要遵循以下规则信号和槽重载二义性问题 4.内存管理1. 简…