python中的深拷贝和浅拷贝_python浅复制和深复制的区别

python中的深拷贝和浅拷贝_python浅复制和深复制的区别薇尔莉特来了~~~~~~

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

这一篇的内容主要是关于python中浅拷贝和深拷贝的原理。博主的其他内容可以在其他专栏中查看,更多内容还在更新中。

在这里插入图片描述
变量赋值的底层逻辑
在这里插入图片描述
在这里插入图片描述

变量赋值机制

num1 = [1,2,3]
num2 = num1 #num1将地址值复制给了num2 (参考将寄存箱小票指向的位置,复制给了num2)
num2.append(4) #所以num2修改了箱子里面的内容,num1取出来的内容也就变了。
print("num1:",num1,id(num1))
print("num2:",num2,id(num2))
#输出
''' num1: [1, 2, 3, 4] 2676183109952 num2: [1, 2, 3, 4] 2676183109952 '''

num1把地址复制给了num2。所以num1和num2指向堆内存中的同一个位置。在这种情况下,无论num1还是num2改变都会导致另一个的改变。

在这里插入图片描述

浅拷贝

再看看下面这个例子:

num1 = [10,[2,3]]
num2 = num1.copy() #将num1所指向的数据内容(地址值),复制了一份给num2

在这里插入图片描述

当执行程序后

num1 = [10,[2,3]]
num2 = num1.copy() #将num1所指向的数据内容(地址值),复制了一份给num2
num2.append(4) 
print("num1:",num1,id(num1)) #num1和num2的地址值不同
print("num2:",num2,id(num2))
num1[0] = 8 
print("num1[0]:",num1[0],id(num1[0]))
print("num2[0]:",num2[0],id(num2[0]))
print("num1[1]:",num1[1],id(num1[1]))
print("num2[1]:",num2[1],id(num2[1]))
#输出:
#num1: [10, [2, 3]] 1664063024384
#num2: [10, [2, 3], 4] 1664063016256
#num1[0]: 8 1664010119696
#num2[0]: 10 1664010119760
#num1[1]: [2, 3] 1664063016576
#num2[1]: [2, 3] 1664063016576

为什么会出现这样的输出结果?

在这里插入图片描述

我们再来看下面这个程序的输出结果

num1 = [10,[2,3]]
num2 = num1.copy() 
num2[1].append(4) 
print(num1)
print(num2)
# 输出
# [10, [2, 3, 4]]
# [10, [2, 3, 4]]

在这里插入图片描述

深拷贝

import copy
num1=[10.[2,3]]
num2=copy.deepcopy(num1)
#在使用深拷贝时,需要引用模块copy

在这里插入图片描述

我们对列表num1,num2做一定的修改

import copy
num1 = [10,[2,3]]
num2 = copy.deepcopy(num1) #将num1所指向的数据元素,复制了一份给num2
# num1[-1].append(8) #所以,修改num1的列表元素中的内容,num2中对应的列表元素也变了
print("num1中列表的地址:",id(num1[-1]),"\nnum2中列表的地址:",id(num2[-1]))
#说明列表中的”列表元素“没有复制元素内容,仅仅复制的是地址。 print("num1:",num1,id(num1))
print("num2:",num2,id(num2))
print("num1[0]:",num1[0],id(num1[0]))
print("num2[0]:",num2[0],id(num2[0]))
print("num1[1]:",num1[1],id(num1[1]))
print("num2[1]:",num2[1],id(num2[1]))
#输出
#num1中列表的地址: 1814079840768 
#num2中列表的地址: 1814079814848
#num2: [10, [2, 3]] 1814079849088
#num1[0]: 10 1814030674512
#num2[0]: 10 1814030674512
#num1[1]: [2, 3] 1814079840768
#num2[1]: [2, 3] 1814079814848

在这里插入图片描述
总结

浅拷贝:只能copy列表的一级元素,复制了嵌套的可变数据类型的地址
深拷贝:能够copy列表所有层级的元素,复制了嵌套的可变数据类型元

在这里插入图片描述

没有合适的画图工具,有些东西没有解释的很清楚,还请见谅。欢迎大家在评论区指正和交流。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188435.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 移动端开发模式

    移动端开发模式移动端开发模式现今流行的移动端开发模式共有三种:web(H5)Hybrid(混合开发)Native(原生)下面来剖析一下三种模式的优缺点:1.开发难度:无疑web和Hybrid难度要小于原生app开发,而且可以利用现有的Web开发工具和工作流程。2.移动设备本地API访问:Hybrid可以通过jsAPI访问移动设备的摄像头,GPS等。原生App可以通

    2022年6月24日
    34
  • 数据库-第一范式、第二范式、第三范式、BC范式、第四范式简析

    数据库-第一范式、第二范式、第三范式、BC范式、第四范式简析在设计与操作维护数据库时,最关键的问题就是要确保数据能够正确地分布到数据库的表中。使用正确的数据结构,不仅有助于对数据库进行相应的存取操作,还可以极大地简化应用程序中的其他内容(查询、窗体、报表、代码等),按照“数据库规范化”对表进行设计,其目的就是减少数据库中的数据冗余,以增加数据的一致性。泛化时在识别数据库中的一个数据元素、关系以及定义所需的表和各表中的项目这些初始工作之后的一个细

    2022年5月24日
    38
  • matlab读取txt文件数据_matlab怎么输入数据

    matlab读取txt文件数据_matlab怎么输入数据文件操作是一种重要的输入输出方式,即从数据文件读取数据或将结果写入数据文件。MATLAB提供了一系列低层输入输出函数,专门用于文件操作。1、文件的打开与关闭1)打开文件在读写文件之前,必须先用fopen函数打开或创建文件,并指定对该文件进行的操作方式。fopen函数的调用格式为:fid=fopen(文件名,‘打开方式’)说明:其中fid用于存储文件句柄值,如果返回的句柄值大于0

    2025年9月19日
    8
  • FileUpload文件上传控件「建议收藏」

    FileUpload文件上传控件「建议收藏」1.FileUpload控件的主要功能是向指定目录上传文件。FileUpload控件不会自动上传控件,而需要设置相关的事件处理程序,然后在程序中实现文件上传。2.FileUpload控件常见的属性

    2022年7月1日
    30
  • TSQL–标示列、GUID 、序列

    TSQL–标示列、GUID 、序列

    2021年8月27日
    54
  • js判断字符串是否为空格_替换字符串c++

    js判断字符串是否为空格_替换字符串c++//判断字符串是否为空functionisNull(variable){if(variable!==null||variable!==undefined||variable!==”){ if(variable.replace(/(^s*)|(s*$)/g,””).length>0){returnfalse} }returntrue;

    2025年8月2日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号