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列表所有层级的元素,复制了嵌套的可变数据类型元

在这里插入图片描述

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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • iOS证书申请_安装证书

    iOS证书申请_安装证书苹果的证书繁锁复杂,制作管理相当麻烦,今天决定重置一个游戏项目中的所有证书,做了这么多次还是感觉很纠结,索性直接记录下来,日后你我他查阅都方便;关于证书苹果使用密文签名技术来验证App的合法性,不管是

  • springmvc的执行流程详解[通俗易懂]

    1.什么是MVCMVC是ModelViewController的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet)第二步:前端控制器请求HandlerMapping查找Handler        可以根据xml配置、注解进行查找第三步:处理器映射器Handle

  • CAP 原理[通俗易懂]

    CAP 原理[通俗易懂]简单记录下分布式数据库的CAP原理

  • java:闰年判断程序[通俗易懂]

    java:闰年判断程序[通俗易懂]公历闰年的简单计算方法(符合以下条件之一的年份即为闰年)1、能被4整除而不能被100整除。2、能被400整除。方案:使用数学运算符取余运算(%),关系运算符等于(==)和不等于(!=),辑运算符逻辑与(&&)和逻辑或(||),来判断某年是否为闰年,判断的结果为boolean类型的值,如果为闰年boolean类型的值为true,否则为falsebooleanflag=(year%4==0&&year%100!=0)||year%400==0

  • 传统线程技术(一)

    传统线程技术(一)

  • intellij idea javaweb_数据库系统原理教程

    intellij idea javaweb_数据库系统原理教程一,简介Eclipse/MyEclipse确实用起来诸多不爽,准备切换IntelliJIDEA,本篇介绍如何配置IDEA并使用IDEA开发一个Web应用。二,软件下载与安装1,首先下载安装JDK并配置环境变量。JDK安装目录D:\Java\jdk1.7.0_79新建环境变量JAVA_HOME,其值为D:\Java\jdk1.7.0_79环境变量PATH中添加%JAVA_HOME%\bin

发表回复

您的电子邮箱地址不会被公开。

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