如何在Python中正确使用浅拷贝和深拷贝?

news2024/11/17 23:48:16

更多资料获取

📚 个人网站:ipengtao.com


在Python编程中,拷贝对象是一个常见的操作,尤其是在处理复杂数据结构时。Python提供了两种拷贝方式:浅拷贝(shallow copy)和深拷贝(deep copy)。了解这两种拷贝方式的区别和使用场景,对于编写高效和正确的代码至关重要。本文将详细介绍浅拷贝和深拷贝的概念、实现方法及其实际应用,并通过示例代码帮助全面理解这两个重要的工具。

浅拷贝和深拷贝的概念

浅拷贝

浅拷贝创建一个新的对象,但不复制对象内部的子对象。新对象中的子对象仍然引用原对象中的子对象。这意味着对新对象的修改可能会影响原对象,反之亦然。

深拷贝

深拷贝创建一个新的对象,同时递归地拷贝原对象内部的所有子对象。新对象与原对象完全独立,修改新对象不会影响原对象,反之亦然。

使用 copy 模块进行拷贝

Python的copy模块提供了copy函数和deepcopy函数,分别用于实现浅拷贝和深拷贝。

import copy

浅拷贝的实现和示例

使用 copy.copy 进行浅拷贝

copy.copy函数用于创建一个对象的浅拷贝。

import copy

# 创建一个列表
original_list = [1, 2, [3, 4], 5]
# 使用copy.copy进行浅拷贝
shallow_copied_list = copy.copy(original_list)

print("原列表:", original_list)
print("浅拷贝列表:", shallow_copied_list)

# 修改浅拷贝列表中的嵌套列表
shallow_copied_list[2][0] = 99

print("修改后原列表:", original_list)
print("修改后浅拷贝列表:", shallow_copied_list)

输出:

原列表: [1, 2, [3, 4], 5]
浅拷贝列表: [1, 2, [3, 4], 5]
修改后原列表: [1, 2, [99, 4], 5]
修改后浅拷贝列表: [1, 2, [99, 4], 5]

从上述示例可以看出,浅拷贝后的对象与原对象共享内部的嵌套对象,因此修改浅拷贝对象中的嵌套对象会影响原对象。

使用切片操作进行浅拷贝

对于列表,可以使用切片操作进行浅拷贝。

# 使用切片操作进行浅拷贝
shallow_copied_list = original_list[:]

print("原列表:", original_list)
print("浅拷贝列表:", shallow_copied_list)

# 修改浅拷贝列表中的嵌套列表
shallow_copied_list[2][0] = 88

print("修改后原列表:", original_list)
print("修改后浅拷贝列表:", shallow_copied_list)

输出:

原列表: [1, 2, [88, 4], 5]
浅拷贝列表: [1, 2, [88, 4], 5]

切片操作与copy.copy函数的效果相同,都是创建一个新的列表对象,但共享内部的嵌套对象。

深拷贝的实现和示例

使用 copy.deepcopy 进行深拷贝

copy.deepcopy函数用于创建一个对象的深拷贝。

import copy

# 创建一个列表
original_list = [1, 2, [3, 4], 5]
# 使用copy.deepcopy进行深拷贝
deep_copied_list = copy.deepcopy(original_list)

print("原列表:", original_list)
print("深拷贝列表:", deep_copied_list)

# 修改深拷贝列表中的嵌套列表
deep_copied_list[2][0] = 77

print("修改后原列表:", original_list)
print("修改后深拷贝列表:", deep_copied_list)

输出:

原列表: [1, 2, [3, 4], 5]
深拷贝列表: [1, 2, [3, 4], 5]
修改后原列表: [1, 2, [3, 4], 5]
修改后深拷贝列表: [1, 2, [77, 4], 5]

从上述示例可以看出,深拷贝后的对象与原对象完全独立,因此修改深拷贝对象中的嵌套对象不会影响原对象。

拷贝复杂对象

浅拷贝复杂对象

class Person:
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age}, address={self.address})"

original_person = Person("Alice", 30, {"city": "New York", "street": "5th Avenue"})
shallow_copied_person = copy.copy(original_person)

print("原对象:", original_person)
print("浅拷贝对象:", shallow_copied_person)

# 修改浅拷贝对象中的嵌套字典
shallow_copied_person.address["city"] = "San Francisco"

print("修改后原对象:", original_person)
print("修改后浅拷贝对象:", shallow_copied_person)

输出:

原对象: Person(name=Alice, age=30, address={'city': 'San Francisco', 'street': '5th Avenue'})
浅拷贝对象: Person(name=Alice, age=30, address={'city': 'San Francisco', 'street': '5th Avenue'})

深拷贝复杂对象

deep_copied_person = copy.deepcopy(original_person)

print("原对象:", original_person)
print("深拷贝对象:", deep_copied_person)

# 修改深拷贝对象中的嵌套字典
deep_copied_person.address["city"] = "Los Angeles"

print("修改后原对象:", original_person)
print("修改后深拷贝对象:", deep_copied_person)

输出:

原对象: Person(name=Alice, age=30, address={'city': 'San Francisco', 'street': '5th Avenue'})
深拷贝对象: Person(name=Alice, age=30, address={'city': 'Los Angeles', 'street': '5th Avenue'})

拷贝自定义对象

有时,我们可能需要拷贝自定义对象。这时,可以通过实现__copy____deepcopy__方法来定制拷贝行为。

实现自定义浅拷贝

class CustomObject:
    def __init__(self, value):
        self.value = value

    def __copy__(self):
        print("执行自定义浅拷贝")
        return CustomObject(self.value)

original_custom = CustomObject(10)
shallow_copied_custom = copy.copy(original_custom)

print("原对象:", original_custom)
print("浅拷贝对象:", shallow_copied_custom)

实现自定义深拷贝

class CustomObject:
    def __init__(self, value):
        self.value = value

    def __deepcopy__(self, memo):
        print("执行自定义深拷贝")
        return CustomObject(copy.deepcopy(self.value, memo))

original_custom = CustomObject(10)
deep_copied_custom = copy.deepcopy(original_custom)

print("原对象:", original_custom)
print("深拷贝对象:", deep_copied_custom)

注意事项

拷贝不可变对象

对于不可变对象,如整数、字符串和元组,浅拷贝和深拷贝的结果是相同的,因为不可变对象的内容不会改变。

original_int = 42
shallow_copied_int = copy.copy(original_int)
deep_copied_int = copy.deepcopy(original_int)

print("原对象:", original_int)
print("浅拷贝对象:", shallow_copied_int)
print("深拷贝对象:", deep_copied_int)

输出:

原对象: 42
浅拷贝对象: 42
深拷贝对象: 42

循环引用

在处理复杂数据结构时,可能会遇到循环引用的情况。深拷贝能够正确处理循环引用,而浅拷贝可能会导致无限循环。

a = [1, 2, 3]
b = [a, 4, 5]
a.append(b)

deep_copied_a = copy.deepcopy(a)
print("深拷贝对象:", deep_copied_a)

输出:

深拷贝对象: [1, 2, 3

, [[...], 4, 5]]

总结

本文详细介绍了Python中浅拷贝和深拷贝的概念、实现方法及其实际应用场景。通过使用copy模块中的copy函数和deepcopy函数,可以分别实现浅拷贝和深拷贝。浅拷贝创建一个新对象,但不复制内部子对象,而深拷贝则递归地复制所有子对象。文章还展示了如何拷贝复杂对象和自定义对象,以及在处理不可变对象和循环引用时的表现。掌握这些技巧,可以帮助大家在开发过程中更好地管理和操作数据结构,提高代码的健壮性和可维护性。


Python学习路线

在这里插入图片描述

更多资料获取

📚 个人网站:ipengtao.com

如果还想要领取更多更丰富的资料,可以点击文章下方名片,回复【优质资料】,即可获取 全方位学习资料包。

在这里插入图片描述
点击文章下方链接卡片,回复【优质资料】,可直接领取资料大礼包。

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

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

相关文章

day35-四层负载

01.四层负载概念 02.四层实现对端口转发 1.克隆一台10.0.0.4 2.安装部署nginx服务 [rootlb:~]# scp 10.0.0.7:/etc/yum.repos.d/nginx.repo /etc/yum.repos.d/[rootlb:~]#yum -y install nginx3.配置nginx四层负载 [rootlb:~]#rm -rf /etc/nginx/conf.d/default.conf # 删除默认…

【重磅发布】2025华清远见新品发布会亮点、新品抢先看!

匠心服务 智启新程 大咖云集 • 行业分析 • 预见趋势 新品首发 • 课程升级 • 育人交流 - 2025华清远见新品发布会 将于2024年8月23日在北京隆重举行 诚邀您的到来! 大会背景 本次新品发布会以 “匠心服务 智启新程”为主题, 邀请多家业内知名…

顶刊中的水刊!中科院1区TOP和“平替”双打组合,3天初审,25天可录用!

高分“水刊” 前面小编解析了一本MDPI旗下能源电力类期刊《Energies》 (👉详情参考:MDPI旗下Energies“平替”:这本SCI又“水”又稳,不卡背景,25天录用吊打同行) 本期解析一本顶刊&#xff0c…

【Python零基础学习】字典

文章目录 前言一、简单字典示例二、使用字典三、字典遍历四、嵌套总结 前言 Python 字典 是一种非常强大且灵活的数据结构,它允许你通过键(key)来存储和检索值(value)。想象一下,字典就像一个巨大的电话簿…

免费分享一套SpringBoot+Vue员工管理(职工管理,考勤管理,奖惩管理,合同管理)管理系统【论文+源码+SQL脚本】,帅呆了~~

大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue员工管理(职工管理,考勤管理,奖惩管理,合同管理)管理系统,分享下哈。 项目视频演示 【免费】SpringBootVue员工管理(职工管理,考勤…

Redis远程字典服务器(6) —— list类型详解

目录 一,基本情况 二,list常用命令 2.1 lpush,lrange 2.2 对于“下标越界”的思考 2.3 lpushx,rpush,rpushx 2.4 lpop,rpop 2.5 lindex,linsert,llen 2.6 lrem 2.7 ltrim…

基于B站的热门视频数据分析与情感分析【关联性、主题、情感分析】

目录 2 研究内容 2.1 主要研究内容 2.2 拟解决的关键问题 2.2.1热门视频特征的识别和提取 2.2.2情感分析与用户反馈 2.3技术路线 2.3.1数据收集 2.3.2数据预处理 2.3.3数据挖掘 2.3.4 数据可视化 2.4可行性分析 2.4.1技术可行性 2.4.2数据可行性 2.4.3经济可行性 2.5数据库设计…

vba发送邮件功能实现方法:如何调试测试?

vba发送邮件的配置步骤流程?vba发送邮件的安全指南? VBA是一种常用于自动化Office应用程序的编程语言。利用VBA发送邮件功能,用户可以实现自动化发送邮件的任务,无需手动操作。AokSend将详细探讨如何通过调试与测试来确保VBA发送…

ThreadLoad如何防止内存溢出

优质博文:IT-BLOG-CN 从 ThreadLocalMap看 ThreadLocal使用不当的内存泄漏问题 【1】基础概念 : 首先我们先看看ThreadLocalMap的类图,我们知道 ThreadLocal只是一个工具类,他为用户提供get、set、remove接口操作实际存放本地变…

MT7621+MT7915(MT7905)+MT7975 (W7621A6G-SDK)编译固件与升级固件方法

一、搭建开发环境,编译固件。 1、安装在Ubuntu 14.04.5 x86_64系统后,然后安装下面命令行。 $ sudo apt-get install git g make libncurses5-dev subversion libssl-dev gawk libxml-parser-perl unzip wget python xz-utils vim zlibc zlib1g zlib1g…

XSS---DOM破坏靶场复现

目录 一、OK,Boomer 一、网址: 二、源码分析: 三、 解决思路: 1.页面中的元素可以通过id和name直接取出来 2.覆盖 3.覆盖方法 四、ToString 五、setTimeout函数 六、使用框架白名单 七、成功绕过 ​编辑 二、案例分析…

才来鱼厂实习 1 个月,就转正了!

大家好,我是程序员鱼皮。昨天,我给才来我们公司 实习一个月 的前端开发同学转正了,直接发了正式 Offer!这个转正速度,放眼到所有公司中,我相信也是炸裂的。 看小伙子那么激动,让我回想到了 19 年…

认识 bufferbloat

很多人并不理解 bufferbloat 的本质,我引用《计算机网络-自顶向下方法(第 8 版)》第四章的一个解释: 很形象的比喻,buffer 就像盐,不可或缺,适量增味,过量食物就不能吃了。高血压患者更有所感受&#xff…

STM32是基于ARM架构的,那么ARM究竟是什么呢?

一、什么是ARM 首先,ARM是一家英国公司,全称Advanced RISC Machines,高级精简指令集机器,RISC意味着是精简指令集的芯片。同时也有复杂指令集CSIC的芯片,如X86,常以Intel和AMD为主。 其次,之后…

如何跳过极狐GitLab 密钥推送保护功能?

极狐GitLab 是 GitLab 在中国的发行版,专门面向中国程序员和企业提供企业级一体化 DevOps 平台,用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规,而且所有的操作都是在一个平台上进行,省事省心省钱。可以一键安装极狐GitL…

vue 子组件全局自动导入,不在需要每个组件import

main.js import vue from vue import App from ./App.vue import axios from axios axios.defaults.baseURL HTTP://LOCALHOST:3000/api/ Vue.prototype.$http axios; vue config.productionTip false; //子组件全局自动导入 const requireComponents require.cont…

MK米客方德推出新一代工业级SD NAND——更长寿命、更高速度、更优功耗

博客目录 关注我,不迷路,共学习,同进步一、产品封装与兼容性二、SLC 存储颗粒的使用三、高性能 IOPS 表现四、智能健康监测功能五、内嵌 ECC 校验、坏块管理和其他保护机制六、低功耗设计总结 作为 SD NAND 领域的领跑者,MK 米客方…

【Chromium】分享一个网址 Chromium Browser Snapshots

利用 Chromium Browser Snapshots 进行开发和调试 author: jwensh & chatgpt date:20240819 文章目录 利用 Chromium Browser Snapshots 进行开发和调试1. 获取最新的浏览器特性2. 测试和调试浏览器兼容性问题3. 开发和测试浏览器扩展4. 安全研究和漏洞分析5. 提前为新特性…

如何一键删除iPhone相册所有照片

拍照已成为我们记录日常生活的常态。但是,大量照片便会积累在设备上,这不仅占用了大量存储空间,而且随着时间的推移,管理这些照片也变得越来越困难。如果你决定清理旧照片,或者出于隐私考虑需要删除所有照片&#xff0…

2024:AI新纪元,轻松打造你的专属AI助手

引入 在数字化时代的潮流中,人工智能已经成为了我们生活中不可或缺的一部分。2024年被誉为“AI元年”,这不仅是因为人工智能技术的飞速发展,更是因为它已经渗透到我们的日常生活中,为我们带来了无数便利和可能性。在这个充满活力…