深入理解 Python 中的浅拷贝与深拷贝

文章目录

  • 1. 基本概念
    • 1.1 前置知识
    • 1.2 浅拷贝(Shallow Copy)
    • 1.3 深拷贝(Deep Copy)
  • 2. 如何实现浅拷贝和深拷贝
  • 3. 深入分析

在 Python 中,数据复制是常见需求。复制机制分为“浅拷贝(shallow copy)”和“深拷贝(deep copy)”,这两种方式在处理复杂数据结构时的行为差异极大。下面详细解析这两种拷贝方法,包括它们的定义、如何使用、适用场景以及它们在内存操作上的不同表现。


1. 基本概念

1.1 前置知识

在 Python 中,所有数据都是以对象的形式表示的,这包括简单的数值、字符串,以及复杂的列表、字典等。

对象可以分为“可变对象”和“不可变对象”。

  • 不可变对象(如整数、字符串和元组)不允许对象本身的内容被改变
  • 可变对象(如列表、字典)则允许对象内容的修改。

1.2 浅拷贝(Shallow Copy)

浅拷贝仅仅复制数据结构的第一层对象本身,如果对象包含了其他对象的引用,则这些引用的地址不变。也就是说,浅拷贝创建了一个新对象,但是这个新对象中填充的是对原始对象内容的引用(即地址)。
在这里插入图片描述

1.3 深拷贝(Deep Copy)

深拷贝对原始数据的完全拷贝,包括数据结构中的所有层级。如果原始对象中含有对其他对象的引用,深拷贝不仅复制结构本身,还会递归地复制所有引用的具体内容,因此新对象与原始对象无任何关联。
在这里插入图片描述

2. 如何实现浅拷贝和深拷贝

Python 的 copy 模块提供了实现浅拷贝和深拷贝的方法。

示例代码

以下代码演示了浅拷贝与深拷贝的基本用法:

import copy# 创建一个包含其他对象的复杂对象
original_list = [1, 2, [3, 4], {'a': 5}]# 浅拷贝: 复制顶层对象,内部容器对象如列表和字典保持引用不变
shallow_copied_list = copy.copy(original_list)# 深拷贝: 完全复制所有层级的对象,无引用关系保留
deep_copied_list = copy.deepcopy(original_list)# 修改原始数据中的列表和字典
original_list[2].append(5)  # 这会影响浅拷贝中的相应列表
original_list[3]['a'] = 6   # 这也会影响浅拷贝中的相应字典# 输出原始数据和两种拷贝的结果
print("Original:", original_list)       # 显示原始对象的当前状态
print("Shallow Copy:", shallow_copied_list)  # 显示浅拷贝对象的当前状态
print("Deep Copy:", deep_copied_list)        # 显示深拷贝对象的当前状态

运行结果

运行上述代码会得到以下输出:

Original: [1, 2, [3, 4, 5], {'a': 6}]
Shallow Copy: [1, 2, [3, 4, 5], {'a': 6}]
Deep Copy: [1, 2, [3, 4], {'a': 5}]
  • 浅拷贝对象的子列表和字典与原始对象一致,因为它们是引用。
  • 深拷贝对象的子列表和字典独立于原始对象,对原始对象的修改不影响深拷贝对象。

3. 深入分析

内存效率

浅拷贝由于只复制一层对象,因此在执行速度和所占内存上比深拷贝更为高效。对于大规模数据结构,频繁使用深拷贝可能导致明显的性能下降。

使用场景

  • 浅拷贝适用于对象结构简单或只需复制顶层结构的场景。比如当需要复制的对象包含大量不可变数据或共享数据时。
  • 深拷贝则适用于需要完全独立副本的复杂数据结构,如多层嵌套的列表或字典。

注意事项

在使用深拷贝时,需要注意递归引用的问题,即对象自身直接或间接地引用了自己。这种情况下,深拷贝会尝试无限复制,最终导致栈溢出错误。


参考:copy in Python (Deep Copy and Shallow Copy)
推荐: python 错误记录

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

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

相关文章

Python项目1 外星人入侵_记分

在本章中,我们将结束游戏《外星人入侵》的开发。我们将添加一个Play按钮,用于根据需要启动游戏以及在游戏结束后重启游戏。我们还将修改这个游戏,使其在玩 家的等级提高时加快节奏,并实现一个记分系统。阅读本章后,你将…

安装 k8s集群的问题:默认容器运行时从 Docker 改为 Containerd

安装 k8s集群的问题:默认容器运行时从 Docker 改为 Containerd 1、背景2、容器运行时从 Docker 改为 Containerd2.1、安装 Containerd:2.2、生成 Containerd 的配置文件2.3 、创建 /etc/crictl.yaml 文件2.4 、配置 Containerd 服务开机自启 &#x1f49…

虹科Pico汽车示波器 | 免拆诊断案例 | 2011款东风悦达起亚K5车发动机偶尔起动困难

一、故障现象 一辆2011款东风悦达起亚K5车,搭载G4KD发动机,累计行驶里程约为24.5万km。车主反映,第1次起动发动机时偶尔无法起动着机,第2次能够正常起动着机,但发动机故障灯异常点亮。为此在其他维修厂维修过&#xf…

在线客服业务架构:构建智能互动与个性化服务

随着数字化时代的到来,在线客服业务正成为企业与客户沟通互动的重要渠道。在这个快节奏的时代,如何构建一个高效、智能的在线客服业务架构成为了企业关注的焦点。本文将探讨在线客服业务架构的重要性,并介绍如何构建智能互动与个性化服务的在…

高清视频素材,免费下载,收藏好这6个网站。

国内大部分视频素材网站都需要付费购买,这让很多从事视频剪辑的朋友不知道去哪里找免费的视频素材,本期就给大家分享我收藏多年的6个视频素材网站,都可以免费下载,还可以商用,而且国内外的都有哦,有需要的朋…

(1)半导体设备之sorter机【下】:HOW TO 业务的开发

sorter 的全面科普文章见 文章 (1)半导体设备之sorter机(上)_晶圆倒片机-CSDN博客 00、背景:晶圆Sorter如何与生产线其他设备协同工作 晶圆Sorter的自动化传输系统是半导体制造过程中的关键组成部分,它与…

Elasticsearch8.x 设置密码

文章目录 一、环境说明二、使用elasticsearch-reset-password工具修改1、elasticsearch-reset-password工具位置2、设置密码 一、环境说明 elasticsearch版本:8.13.0 系统版本:Ubuntu 18.04.6 二、使用elasticsearch-reset-password工具修改 1、elast…

根据状态转移图实现时序电路

描述 某同步时序电路的状态转换图如下,→上表示“C/Y”,圆圈内为现态,→指向次态。 请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。 如图所示: 电路的接口如下图所示,C是单bit数据…

Kubernetes篇(五)— Pod详解下篇

目录 前言Pod调度定向调度亲和性调度污点和容忍 前言 本章节将详细介绍Pod资源的各种配置(yaml)和原理。 Pod调度 ​ 在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程…

基于SSM+Jsp+Mysql的大学生校园兼职系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

HarmonyOS实战开发-本示例模拟倒计时场景,如何实现振动。

介绍 本示例模拟倒计时场景,通过ohos.vibrator 等接口来实现振动。 效果预览 使用说明 1.点击倒计时文本,弹出时间选择框,选择任意时间,点击确认,倒计时文本显示选择的时间。 2.点击start,开始倒计时&a…

Java POI (5)—— 复杂报表导出案例

一、需求分析 某个仪器会连续采集1~4通道的16进制的原始数据,现在需要将这些数据,先按照通道进行分类,然后将分好类的数据进行处理,转化成10进制,再最终带入到一个拟合公式,得到处理后的数据,然…