Python中的深拷贝与浅拷贝:深入解析与实用指南

Python中的深拷贝与浅拷贝:深入解析与实用指南

一、引言

在Python编程中,我们经常需要复制对象,但有时候仅仅复制对象的引用是不够的,我们需要的是对象的真实副本。此时,我们就需要考虑使用深拷贝或浅拷贝。深拷贝和浅拷贝是Python中两种常见的对象复制方式,它们之间的主要区别在于复制的深度和方式。本文将详细解析深拷贝和浅拷贝的概念、原理、区别以及应用场景,帮助读者更好地理解和使用这两种复制方式。

二、浅拷贝(Shallow Copy)

浅拷贝,也被称为浅复制或对象复制,是Python中对象复制的一种基本方式。在浅拷贝中,对于非容器类型(如整数、浮点数、字符串等)的对象,直接复制其值;而对于容器类型(如列表、字典、元组、集合等)的对象,只复制容器本身,而不复制容器内的对象。换句话说,浅拷贝只复制一层,如果容器内嵌套了其他容器,那么这些嵌套的容器只是被引用,而不是被复制。

在Python中,可以使用copy模块中的copy()函数或者切片操作(对于列表和元组)来实现浅拷贝。以下是一个使用copy()函数进行浅拷贝的示例:

import copy# 原始列表
original_list = [1, 2, [3, 4], 5]# 浅拷贝列表
shallow_copy_list = copy.copy(original_list)# 修改浅拷贝列表中的嵌套列表
shallow_copy_list[2][0] = 'a'# 输出原始列表和浅拷贝列表
print("Original List:", original_list)  # 输出: [1, 2, ['a', 4], 5]
print("Shallow Copy List:", shallow_copy_list)  # 输出: [1, 2, ['a', 4], 5]

从上面的示例可以看出,当我们修改浅拷贝列表中的嵌套列表时,原始列表中的对应嵌套列表也被修改了。这是因为浅拷贝只复制了最外层的容器,而没有复制嵌套容器及其内部的对象。

三、深拷贝(Deep Copy)

深拷贝,也被称为深度复制或完全复制,是Python中对象复制的另一种方式。在深拷贝中,对于非容器类型的对象,直接复制其值;而对于容器类型的对象,不仅复制容器本身,还递归地复制容器内的所有对象(包括嵌套容器及其内部的对象)。换句话说,深拷贝会复制对象的所有层次,直到最底层的基本数据类型。

在Python中,可以使用copy模块中的deepcopy()函数来实现深拷贝。以下是一个使用deepcopy()函数进行深拷贝的示例:

import copy# 原始列表
original_list = [1, 2, [3, 4], 5]# 深拷贝列表
deep_copy_list = copy.deepcopy(original_list)# 修改深拷贝列表中的嵌套列表
deep_copy_list[2][0] = 'a'# 输出原始列表和深拷贝列表
print("Original List:", original_list)  # 输出: [1, 2, [3, 4], 5]
print("Deep Copy List:", deep_copy_list)  # 输出: [1, 2, ['a', 4], 5]

从上面的示例可以看出,当我们修改深拷贝列表中的嵌套列表时,原始列表并没有受到影响。这是因为深拷贝递归地复制了所有层次的对象,包括嵌套容器及其内部的对象。

四、深拷贝与浅拷贝的区别

深拷贝和浅拷贝的主要区别在于复制的深度和方式。浅拷贝只复制最外层的容器和容器内的非容器对象,而容器内的容器对象只是被引用,而不是被复制。因此,当修改浅拷贝中的嵌套容器时,原始对象也会受到影响。而深拷贝则递归地复制所有层次的对象,包括嵌套容器及其内部的对象。因此,修改深拷贝中的对象不会影响原始对象。

另外,需要注意的是,由于深拷贝需要递归地复制所有层次的对象,因此它通常比浅拷贝更耗时和更耗内存。因此,在选择使用深拷贝还是浅拷贝时,需要根据具体的应用场景和需求进行权衡。

五、应用场景

  1. 浅拷贝的应用场景:当只需要复制最外层的容器和容器内的非容器对象时,可以使用浅拷贝。例如,当处理不包含嵌套容器的列表或字典时,浅拷贝是一种简单而高效的方式。

  2. 深拷贝的应用场景:当需要复制所有层次的对象,包括嵌套容器及其内部的对象时,应该使用深拷贝。例如,在处理包含嵌套容器(如列表的列表、字典的字典等)的复杂数据结构时,深拷贝能够确保复制出的新对象与原对象完全独立,互不干扰。

六、深拷贝与浅拷贝的注意事项

  1. 不可变对象:对于不可变对象(如数字、字符串、元组等),由于它们本身的值不能被修改,因此无论是深拷贝还是浅拷贝,结果都是相同的。也就是说,对于这些对象,我们无需担心拷贝后的修改会影响原始数据。
  2. 内存和性能:如上所述,深拷贝需要递归地复制所有层次的对象,因此通常比浅拷贝更耗时和更耗内存。在处理大型数据结构时,这可能会成为一个问题。因此,在选择使用深拷贝还是浅拷贝时,需要根据具体的应用场景和需求进行权衡。
  3. 循环引用:在某些情况下,对象之间可能存在循环引用(即一个对象直接或间接地引用了自己)。在进行深拷贝时,这种循环引用可能会导致问题,因为深拷贝会不断地递归复制对象,直到达到最底层的基本数据类型。如果在这个过程中遇到了已经复制过的对象,就可能会导致无限递归或内存溢出。因此,在使用深拷贝时,需要特别注意循环引用的问题。

七、总结

深拷贝和浅拷贝是Python中两种常见的对象复制方式,它们的主要区别在于复制的深度和方式。浅拷贝只复制最外层的容器和容器内的非容器对象,而深拷贝则递归地复制所有层次的对象。在选择使用深拷贝还是浅拷贝时,需要根据具体的应用场景和需求进行权衡。同时,还需要注意不可变对象、内存和性能以及循环引用等问题。希望本文能够帮助读者更好地理解和使用Python中的深拷贝和浅拷贝。

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

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

相关文章

GPT-2添加PAD token

GPT-2和GPT-3模型(包括其他类似系列)通常没有内置的PAD token,因为它们主要用于生成任务,而这些任务通常不需要填充。然而,在一些特定任务(如批量处理或序列对齐)中,添加PAD token是…

翻译《The Old New Thing》- What‘s the deal with the EM_SETHILITE message?

Whats the deal with the EM_SETHILITE message? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071025-00/?p24693 Raymond Chen 2007年10月25日 简要 文章讨论了EM_SETHILITE和EM_GETHILITE消息在文档中显示为“未实现”的原因。这些…

前端 JS 经典:Web 性能指标

什么是性能指标:Web Performance Metrics 翻译成 Web 性能指标,一般和时间有关系,在短时间内做更多有意义的事情。 一个站点表现得好与不好,标准在于用户体验,而用户体验好不好,有一套 RAIL 模型来衡量。这…

大专学历java能找到工作吗

就低学历就业的情况,大专学历的职业上限基本上是中小公司的开发小组长,中专或同等学历的职业上限一般是软件小作坊的项目经理。当下大专学历能进大公司的可能性不能说没,但相比前几年,少了太多。有稳定业务渠道的软件公司&#xf…

Vue.js功能实现博客

Vue.js功能实现博客 一、前言 Vue.js 是一款构建用户界面的渐进式框架。今天我们将通过一个简单的示例来展示如何使用 Vue.js 创建一个简单的计数器功能,并在此过程中解释每个步骤。 二、环境准备 在开始之前,请确保你的开发环境中已经安装了 Node.j…

音视频学习规划

文章目录 概述闲聊点 小结 概述 最近在学习音视频,觉得还是要先写个提纲,给自己制定下学习路线及目标。先写下我的个人流程及思路。 ffmpeg的命令ffmpeg api播放器流媒体RTMP,HLS 闲聊点 先说下学习命令行吧,学习命令行是为了…

GitHub的原理及应用详解(六)

本系列文章简介: GitHub是一个基于Git版本控制系统的代码托管平台,为开发者提供了一个方便的协作和版本管理的工具。它广泛应用于软件开发项目中,包括但不限于代码托管、协作开发、版本控制、错误追踪、持续集成等方面。 GitHub的原理可以简单…

Spring Cloud 项目在网关聚合 Swagger 文档

文章目录 Spring Cloud 项目在网关聚合 Swagger 文档各个微服务的改动改动一:新增依赖改动二:新增配置类关键项说明 Gateway 的改动改动一:新增依赖改动二:新增配置类和处理类改动三:改动配置文件 Spring Cloud 项目在…

一千题,No.0026(Ternary String)

描述 You are given a string s such that each its character is either 1, 2, or 3. You have to choose the shortest contiguous substring of s such that it contains each of these three characters at least once. A contiguous substring of string s is a string …

Python3 笔记:IDLE的几个基本设置

1、设置字体: Options > Configure IDLE > Fonts 2、设置文字颜色(设置高亮): Options > Configure IDLE > Highlights 3、设置背景颜色: Options > Configure IDLE > Highlights 4、设置窗口&a…

各位数字和-第13届蓝桥杯选拔赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第72讲。 各位数字和&#…

MongoDB(介绍,安装,操作,Springboot整合MonggoDB)

目录 MongoDB 1 MongoDB介绍 MongoDB简介 MongoDB的特点 MongoDB使用场景 小结 2 MongoDB安装 安装MongoDB 连接MongoDB MongoDB逻辑结构 MongoDB数据类型 小结 3 MongoDB操作 操作库和集合 操作文档-增删改 操作文档-查询 MongoDB索引 小结 4 SpringBoot整合…

c# sqlite使用

安装包 使用 const string strconn "Data Sourcedata.db"; using (SQLiteConnection conn new SQLiteConnection(strconn)) {conn.Open();var cmd conn.CreateCommand();cmd.CommandText "select 1";var obj cmd.ExecuteScalar();MessageBox.Show(ob…

ES 查询踩坑-全字段匹配

需求:name字段需要全匹配查询 name的映射 普通的must查询 GET power_engin/_search {"from": 0,"size": 10,"query": {"bool": {"must": [{"term": {"name": {"value": "尼…

刷题之路径总和Ⅲ(leetcode)

路径总和Ⅲ 这题和和《为K的数组》思路一致&#xff0c;也是用前缀表。 代码调试过&#xff0c;所以还加一部分用前序遍历数组和中序遍历数组构造二叉树的代码。 #include<vector> #include<unordered_map> #include<iostream> using namespace std; //Def…

python从入门到精通01

一、程序员计算器 number int(input("请输入一个数字&#xff1a;")) print("二进制",bin(number)) print("八进制",oct(number)) print("十六进制",hex(number))二、给电影打分 score int(input("请给电影《肖申克的救赎》打…

计算机毕业设计Hadoop+Hive地震预测系统 地震数据分析可视化 地震爬虫 大数据毕业设计 Spark 机器学习 深度学习 Flink 大数据

2024 届本科毕业论文&#xff08;设计&#xff09; 基于Hadoop的地震预测的 分析与可视化研究 姓 名&#xff1a;____田伟情_________ 系 别&#xff1a;____信息技术学院___ 专 业&#xff1a;数据科学与大数据技术 学 号&#xff1a;__2011103094________ 指导…

【大数据面试题】33 Flink SQL做过哪些优化?

一步一个脚印&#xff0c;一天一道面试题 简单写几个 Flink SQL 的优化 1.优化状态管理 Flink 的状态管理对整个程序的性能有较大影响。所以优化效果比较好。 设置空闲状态自动清理&#xff08;TTL Time-to-Live&#xff09;数据量大时选择 RocksDBStateBackend // 设置状…

《图解支付系统设计与实现》电子书_V20240525

相较于上次公开发布的V20240503版本&#xff0c;变更内容如下&#xff1a; 根据掘金网友zz67373&#xff08;李浩铭&#xff09;的勘误建议&#xff0c;优化了部分描述。增加&#xff1a;金额处理规范&#xff0c;低代码报文网关实现完整代码&#xff0c;分布式流控等内容。扩…

Java虚拟机原理(下)-Dalvik vs ART-探秘Android虚拟机内在机制

Android系统作为移动端主流平台&#xff0c;其高效的虚拟机无疑是其核心竞争力之一。今天&#xff0c;就让我们一起剥开Dalvik和ART虚拟机的外衣&#xff0c;深入解析它们的工作原理和优缺点&#xff0c;帮助你全面把握Android系统的运行机制。 正文导览 Dalvik和ART虚拟机的发…