Python 浅拷贝(shallow copy)和 深拷贝(deep copy)的区别

2023-11-28 10:32

本文主要是介绍Python 浅拷贝(shallow copy)和 深拷贝(deep copy)的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

深拷贝和浅拷贝都是对对象进行复制生成一个相同对象的过程,它们的本质区别是拷贝出来的对象的地址是否和原对象一样

 

拷贝对象分为两种:可变对象和不可变对象

可变对象(列表,字典):指一个对象在不改变内存所指地址的前提,改变元素的值

不可变对象(数字,字符串,元组):对象的值修改后,对象内存所指的地址也会相应发生改变

 

浅拷贝:
  是指复制过程中,只复制一层变量,不会复制深层变量绑定的对象的复制过程

深拷贝:

      是指复制过程中,复制深层变量绑定的对象的复制过程

当拷贝对象为不可变对象时,不管是copy(浅拷贝)还是deepcopoy(深拷贝),新对象和原有对象的ID指向的都是同一个地址,和赋值(=)的情况一样,举例说明:

import copycopy_str = 'hello word'
copy_str1 = copy.copy(copy_str)#浅拷贝
copy_str2 = copy.deepcopy(copy_str)#深拷贝print(id(copy_str))
print(id(copy_str1))
print(id(copy_str2))#结果:
#11936352
#11936352
#11936352

打印结果是一样的,自己可以试验一下原对象数据类型为元组和数字的情况,结果是一样的;

 

当拷贝对象为可变类型时,还要分两种情况,第一种是原对象为单层结构(对象中无复杂子元素,如:[1,2,3]),第二种是原对象为多层结构(对象中有复杂子对象,如:列表的子元素为列表,[1,[2],3)

第一种情况(原对象为单层结构):拷贝的对象无复杂子对象,无论是copy(浅拷贝)还是deepcopoy(深拷贝),原对象的值发生改变不会影响新对象的值,同时新对象的值发生改变也不会影响原来对象的值,原来对象的ID和新对象的ID不同,如:

import copycopy_list = [1,2]
copy_list1 = copy.copy(copy_list)
copy_list2 = copy.deepcopy(copy_list)print(id(copy_list),id(copy_list1),id(copy_list2))#结果
#50722336 50722296 50722256

可以对新对象和原有对象进行修改操作,看是否会影响其他对象的值;

 

第二种情况(原对象为多层结构,这是重点) :拷贝对象有复杂子对象,使用copy进行浅拷贝时,改变原来对象中复杂子对象元素的值时,新对象中对应的值也会相应发生改变,同理,改变新对象中复杂子对象的元素的值,原来对象对应的值也会发生改变,使用deepcopy进行拷贝时,完全复制独立,修改互不影响对应的值

import copycopy_list = [[1],2]
copy_list1 = copy.copy(copy_list)#浅拷贝
copy_list2 = copy.deepcopy(copy_list)#深拷贝
print(id(copy_list),id(copy_list1),id(copy_list2))
#结果
#52168224 52168184 52168144copy_list[0][0] = 10
print(copy_list,copy_list1)
#结果
[[10], 2] [[10], 2]copy_list1[0][0] = 5
print(copy_list,copy_list1)
#结果
[[5], 2] [[5], 2]print(id(copy_list[0][0]),id(copy_list1[0][0]))
#结果
#1355965648 1355965648copy_list[0][0] = 10
print(copy_list,copy_list2)
#结果
[[10], 2] [[1], 2]copy_list2[0][0] = 5
print(copy_list,copy_list2)
#结果,现在copy_list的第一个值为10,是因为上面修改的原因,也可以使用不改变的copy_list,值则为1
[[10], 2] [[5], 2]print(id(copy_list[0][0]),id(copy_list2[0][0]))
#结果
#1355965648 1355965584

 

通过代码得到验证,通过浅拷贝(copy)复制,原来对象和新对象的复杂子元素的ID是一样的,而通过深拷贝(deepcopy)复制,原来对象和新对象的复杂子元素的ID是不一样的

注意事项:

深拷贝通常只对可变对象进行深层复制,不可变对象通常不会被复制。(复制的是对象的单层结构,深层对象是引用)

 

 

 

 

 

 

 

 

 

 

 

 

 

这篇关于Python 浅拷贝(shallow copy)和 深拷贝(deep copy)的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/429549

相关文章

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

一文深入详解Python的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

Python UV安装、升级、卸载详细步骤记录

《PythonUV安装、升级、卸载详细步骤记录》:本文主要介绍PythonUV安装、升级、卸载的详细步骤,uv是Astral推出的下一代Python包与项目管理器,主打单一可执行文件、极致性能... 目录安装检查升级设置自动补全卸载UV 命令总结 官方文档详见:https://docs.astral.sh/