一文了解浅复制和深复制的工作原理、它们的差异以及用例
off999 2024-10-29 14:59 38 浏览 0 评论
在在 Python 中,复制对象是一项常见任务,尤其是在处理列表、字典和类等复杂数据结构时。然而,由于浅复制操作和深复制操作之间的区别,Python 中的复制可能很棘手。如果您不小心,修改复制的对象可能会无意中更改原始对象,这可能会导致代码中出现意外行为。
Python 中的复制是什么?
Python 中的复制是指创建一个与现有对象重复的新对象。然而,根据复制的方式,这个新对象可以有不同的行为方式。 Python 提供了两种主要的复制方法:
- 浅复制:创建一个新对象,但不递归复制嵌套对象内的元素。相反,它引用复制对象中的原始对象。
- 深度复制:创建一个新对象并递归复制原始对象中找到的所有对象,这意味着即使是嵌套对象也会被完全复制,并且不会与原始对象共享任何引用。
在深入研究浅拷贝和深拷贝之前,重要的是要了解 Python 变量不存储实际值,而是存储对对象的引用。当复制一个对象时,实际上是在创建另一个引用,并且根据它是浅复制还是深复制,可能会也可能不会复制整个结构。
Python 中的浅复制
浅拷贝创建一个新对象,但它只复制对原始对象内元素的引用。换句话说,它复制对象的结构,但其中的内容(例如其他列表、字典或自定义对象)仍然在原始对象和复制对象之间共享。这意味着对复制对象内的可变元素的任何更改都将反映在原始对象中,反之亦然。
浅拷贝如何工作
浅拷贝复制对象的顶层结构,但其中的嵌套对象不会被复制——它们只是被引用。这意味着,如果原始对象包含对其他可变对象(如列表、字典或类实例)的引用,则原始对象和浅拷贝都将指向相同的内部对象。
浅拷贝的语法:
- 使用copy()方法:Python 中的许多内置类型(例如列表和字典)都有执行浅复制的copy()方法。
new_list = old_list.copy()- 使用copy模块:还可以使用copy模块的copy()函数显式执行浅复制。
import copy
new_object = copy.copy(old_object)用法和示例
一个简单的例子来演示浅复制。
import copy
# Original list with a nested list
original_list = [[1, 2, 3], [4, 5, 6]]
shallow_copied_list = copy.copy(original_list)
# Modifying the shallow copy
shallow_copied_list[0][0] = 100
# Output
print("Original List:", original_list)
print("Shallow Copied List:", shallow_copied_list)输出:
Original List: [[100, 2, 3], [4, 5, 6]]
Shallow Copied List: [[100, 2, 3], [4, 5, 6]]在此示例中,原始副本和浅表副本都引用相同的嵌套列表。更改复制列表中的元素也会影响原始列表,因为它们共享相同的内部对象。
注意:仅复制外部结构(列表),但不复制内部列表。
Python 中的深度复制
深复制创建一个新对象并递归复制在原始对象中找到的所有对象。这意味着深度复制不仅复制对象的外部结构,而且复制所有嵌套对象,从而创建全新的独立对象。与浅拷贝不同,对复制对象所做的更改不会影响原始对象,即使在处理嵌套对象时也是如此。
深拷贝的工作原理
在深层复制中,结构中的每个对象(包括任何嵌套对象)都是完全复制的,确保原始对象和副本之间不存在共享引用。这使得复制的对象可以独立于原始对象进行修改,而不会产生任何意外副作用的风险。
深层复制的语法:
- 使用copy模块:要执行深度复制,您可以使用Python copy模块中的deepcopy()函数。
import copy
deep_copied_object = copy.deepcopy(original_object)用法和示例
让我们看一下深层复制的实际应用示例。
import copy
# Original list with a nested list
original_list = [[1, 2, 3], [4, 5, 6]]
deep_copied_list = copy.deepcopy(original_list)
# Modifying the deep copy
deep_copied_list[0][0] = 100
# Output
print("Original List:", original_list)
print("Deep Copied List:", deep_copied_list)输出:
Original List: [[1, 2, 3], [4, 5, 6]]
Deep Copied List: [[100, 2, 3], [4, 5, 6]]在此示例中,深层复制创建嵌套列表的完全独立的副本。对深度复制列表所做的更改不会影响原始列表,因为每个嵌套对象都是完全独立的。
何时使用深层复制
当处理包含嵌套可变对象的复杂数据结构并且需要整个结构的完全独立的副本时,深层复制非常有用。这确保了对复制对象的任何修改都不会影响原始对象。
浅复制和深复制之间的主要区别
在 Python 中使用可变对象时,了解浅复制和深复制之间的主要区别至关重要。虽然这两种操作都会创建新对象,但它们在处理嵌套对象和引用的方式上存在显着差异。
1. 内存分配
- 浅复制:
浅拷贝创建一个新对象,但不会创建原始对象中引用的对象的新副本。相反,它重用对原始嵌套对象的引用。因此,浅拷贝的内存效率更高,因为它们不会复制所有对象,但如果共享引用之一被修改,这可能会导致意想不到的后果。
- 深复制:
深层复制为顶级结构和所有嵌套对象创建全新的对象。每个对象都是唯一的副本,原始对象和副本之间没有共享引用。虽然这会消耗更多内存,但它确保了原始对象和复制对象之间的完全独立性。
2. 对象引用
- 浅复制:
在浅拷贝中,外部对象被复制,但对嵌套对象的引用是共享的。这意味着对浅复制中的可变元素的更改也会影响原始对象,因为它们引用相同的嵌套对象。
例子:
import copy
original = [[1, 2], [3, 4]]
shallow_copy = copy.copy(original)
shallow_copy[0][0] = 99
print("Original:", original) # [[99, 2], [3, 4]] (affected)- 深复制:
在深层复制中,所有对象(包括嵌套对象)都被递归复制,这意味着对内部对象的引用不被共享。对深层副本的更改不会影响原始副本。
例子:
import copy
original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[0][0] = 99
print("Original:", original) # [[1, 2], [3, 4]] (not affected)3. 性能考虑
- 浅复制:
浅拷贝速度更快,消耗的内存更少,因为只复制顶级对象。当您不需要独立修改嵌套对象或使用没有嵌套可变元素的简单数据结构时,它们非常适合。
- 深复制:
深度复制可能会更慢并消耗更多内存,因为它们递归地复制所有对象。它们对于包含嵌套可变对象的复杂数据结构非常有用,其中需要原始对象和复制对象之间完全独立。
4. 用例适用性
- 浅复制:
当只需要复制外部结构并且不打算修改嵌套对象时,这是理想的选择。在处理大型、简单的数据结构时,它对于性能也很有用。
- 深复制:
最适合需要对象及其所有嵌套元素的完整、独立副本的场景。深复制在对副本的任何修改不应影响原始副本的情况下特别有用。
相关推荐
- 戴尔官网保修查询入口(戴尔售后保质期查询)
-
可以按照以下步骤查询戴尔笔记本电脑的保修期:1.打开戴尔官网:https://www.戴尔.com/zh-cn/售后服务/保修政策.html2.点击页面上方的“服务与支持”按钮,进入戴尔的服务支持...
- 手机号邮箱登录入口(手机号邮箱官网)
-
手机163邮箱登录入口如下:163邮箱官网入口:https://smart.mail.163.com/login.htm点击进入登录或者注册邮箱即可。手机浏览器访问进入官网http://www.123...
- sd卡(sd卡无法读取怎么修复)
-
SD卡是大卡,相机用的;普通的手机内存卡,是小卡,正规的名称是macrosd卡,也就是微型SD卡。可以通过卡套转为普通的SD卡的大小。 其实就是大小不同。但手机上的内存卡,人们经常也俗称为SD...
- windows7蓝牙功能在哪里打开
-
点击搜索框在windows7系统主界面点击开始菜单,点击打开搜索框。输入命令输入services.msc后回车,在列表中找到并右击BluetoothSupportS...点击属性选择进入属性菜单,...
-
- 2010激活密钥(microsoft2010激活密钥)
-
步骤/方式1officeprofessionalplus2010:(office专业版)6QFdx-pYH2G-ppYFd-C7RJM-BBKQ8Bdd3G-xM7FB-Bd2HM-YK63V-VQFdKVYBBJ-TRJpB-QFQ...
-
2025-11-19 04:03 off999
- 联想官方刷新bios工具(联想电脑刷新bios)
-
刷新BIOS需要使用联想的官方网站或授权维修中心来进行操作。以下是一些基本步骤:1.访问联想的官方网站,找到BIOS更新程序并下载。在下载过程中,请确保选择与您计算机型号匹配的版本。2.将下载的B...
-
- 苹果ios14系统下载(苹果ios14.1下载)
-
1方法一步骤/方式一打开Appstore。步骤/方式二在搜索栏点击搜索框。步骤/方式三搜索并点击需要下载的软件。步骤/方式四点击获取。步骤/方式五最后验证ID密码即可。1.在应用商店搜索你要下载的应用名称。2.点击下载按钮,如果要求登...
-
2025-11-19 03:03 off999
- office2010怎么免费永久激活密钥
-
用这个试试,一个KMS激活工具可以激活2010到2019的Office自家的目前用的就是这个microsoft6477.moe/1716.html直接使用这个Microsoftoffice2010...
-
- 类似爱加速的国内ip(类似爱加速的app)
-
推荐“V8盒子”。这一款免费无广告的模拟器,不同于其它软件盒子,而是类似于X8沙箱,满足游戏多开,画中画,悬浮球操作,熄屏后台运行等多功能的沙箱盒子.支持一键root,一键安装xposed框架,能在安卓/苹果手机上运行多个安卓/ios虚拟系...
-
2025-11-19 02:03 off999
- 阿里旺旺手机客户端(阿里旺旺手机app)
-
手机淘宝的旺旺在打开商品后,会看到左下角有个旺旺的图标,点击就可以联系了。 阿里旺旺是将原先的淘宝旺旺与阿里巴巴贸易通整合在一起的一个新品牌。它是淘宝和阿里巴巴为商人量身定做的免费网上商务沟通软件,...
- 最纯净的pe装机工具(pe工具哪个纯净)
-
U盘装系统步骤:1.制作U盘启动盘。这里推荐大白菜U盘启动盘制作工具,在网上一搜便是。2.U盘启动盘做好了,我们还需要一个GHOST文件,可以从网上下载一个ghost版的XP/WIN7/WIN8系统,...
- 装一个erp系统多少钱(wms仓库管理软件)
-
现在主流有客户端ERP和云端ERP两种客户端通常一次买断,价格在万元左右,但是还有隐性费用,你需要支付服务器、数据管理员,此外如果系统需要更新维护,你还需要支付另外一笔不菲的费用。云端ERP:优势...
- cad2014序列号和密钥永久(autocad2014序列号和密钥)
-
1在cad2014中修改标注样式后,需要将其保存2单击“样式管理器”按钮,在弹出的窗口中选择修改后的标注样式,然后单击“设置为当前”按钮,再单击“保存当前样式”按钮,将其保存为新的样式名称3为了...
- qq修改密保手机号(qq修改密保手机号是什么意思)
-
QQ更改绑定的手机号码操作步骤如下:1、打开手机主界面,找到“QQ”软件点击打开。2、输入正确的QQ账户和密码登录到qq主界面。3、点击左上角的头像“图片”,进入到个人中心界面。4、进入到个人中心界面...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
慕ke 前端工程师2024「完整」
-
失业程序员复习python笔记——条件与循环
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
