(Python)可变类型不可变类型;引用传递值传递;浅拷贝深拷贝

从一段代码开始说事,先上代码:

a = [[1],[2],[3]]
b = [[4,5],[6,7],[7,8]]
for i,j in zip(a,b):
    print(i,j)
    i = [9]
    #i[0] = 8
    j[:2]=[1,2]
    print(i, j)
print(a)
print(b)

运行的结果:

[1] [4, 5]
[9] [1, 2]
[2] [6, 7]
[9] [1, 2]
[3] [7, 8]
[9] [1, 2]
[[1], [2], [3]]
[[1, 2], [1, 2], [1, 2]]

可以看到修改i的值不会造成数组a的值的修改,而修改j的值会造成数组b的值的修改,这是为什么呢?

可变类型与不可变类型

可变数据类型 :

当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。

不可变数据类型:

当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。

可变数据类型与不可变数据类型_可变类型和不可变类型-CSDN博客

引用传递与值传递

引用传递(Pass by Reference)

在引用传递中,函数接收的是变量的地址,也就是对象的引用。
当你把一个可变对象(如列表、字典等)传递给函数时,函数内部对该对象的修改会影响到原始的对象。
这是因为函数接收的是对象的引用,而不是对象的副本。
示例:

  def modify_list(lst):
      lst[0] = 'changed'

  my_list = [1, 2, 3]
  modify_list(my_list)
  print(my_list)  # 输出 ['changed', 2, 3]

值传递(Pass by Value)

在值传递中,函数接收的是变量的值的副本。
当你把一个不可变对象(如整数、字符串等)传递给函数时,函数内部对该变量的修改不会影响到原始的变量。
这是因为函数接收的是变量的值的副本,而不是变量本身。
示例:

  def modify_int(x):
      x = 'changed'

  my_int = 10
  modify_int(my_int)
  print(my_int)  # 输出 10

总的来说,在 Python 中,变量的赋值行为遵循以下规则:
对于可变对象,变量存储的是对象的引用,即引用传递。
对于不可变对象,变量存储的是对象的值,即值传递。

对一开始的问题做出简化,看以下两段代码

import copy

b = [[4,5],[6,7],[7,8]]
c = b[0]

print(id(b[0]))
print(id(c))

d = [1,2]
print(id(d))
print(id(d[0]),id(d[1]))

c = d
print(id(c))
print(id(c[0]),id(c[1]))
print(b)

数出的结果是

140383141636032
140383141636032
140381758507008
140383142445296 140383142445328
140381758507008
140383142445296 140383142445328
[[4, 5], [6, 7], [7, 8]]

可以看到以c=d这种方式改变c并不会修改b的值,因为这是一个最外层引用传递,此时c指定d指向的可变类型(数组)

import copy

b = [[4,5],[6,7],[7,8]]
c = b[0]

print(id(b[0]))
print(id(c))

d = [1,2]
print(id(d))
print(id(d[0]),id(d[1]))

c[:2] = d
print(id(c))
print(id(c[0]),id(c[1]))
print(b)

输出的结果是

140452090626176
140452090626176
140450707604352
140452091609328 140452091609360
140452090626176
140452091609328 140452091609360
[[1, 2], [6, 7], [7, 8]]

可以看到以c[:2]=d的这种方式,就是先进入c指向的可变数据类型的地址也就是进入到b[0]内部,找到b[0]内部存储的两个子对象的地址,再更改这两个子对象的地址,所以以这种方法更改c也会跟着更改原始的b。

看这个图会有更深入的理解

还看不懂看这个

一文读懂 Python 值传递和引用传递_python 引用传递-CSDN博客

浅拷贝与深拷贝

浅拷贝

只拷贝了对象,对象内的元素并不会发生拷贝。

深拷贝

不仅拷贝对象,对象内的元素也会发生拷贝。

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

上代码

import copy

b = [[4,5],[6,7],[7,8]]
print(id(b))
print(id(b[0]),id(b[1]))

c = copy.copy(b)
print(id(c))
print(id(c[0]),id(c[1]))

e = copy.deepcopy(b)
print(id(e))
print(id(e[0]),id(e[1]))

运行结果

140133587657344
140134970720384 140133587652608
140133587657216
140134970720384 140133587652608
140133587657152
140133587847808 140133587847232

与上述描述相同

但是浅拷贝和深拷贝对处理可变类型数据与不可变类型数据还会有一些差异

更详细的内容请阅读:

一篇就懂:python浅拷贝copy与深拷贝deepcopy_python deepcopy-CSDN博客

可以结合以下代码来理解一下

import copy

b = [[4,5],[6,7],[7,8],9]
e = [1,9]
print(id(b))
print(id(b[0]),id(b[1]))

c = copy.copy(b)
print(c)
b[0][:] = e
print(b)
print(c)
b[3] = 3
print(b)
print(c)

上述代码的输出是

140440909761280
140442292905920 140440909723776
[[4, 5], [6, 7], [7, 8], 9]
[[1, 9], [6, 7], [7, 8], 9]
[[1, 9], [6, 7], [7, 8], 9]
[[1, 9], [6, 7], [7, 8], 3]
[[1, 9], [6, 7], [7, 8], 9]

参考文献

浅拷贝与深拷贝的区别_深拷贝和浅拷贝的区别-CSDN博客

可变数据类型与不可变数据类型_可变类型和不可变类型-CSDN博客

一文读懂 Python 值传递和引用传递_python 引用传递-CSDN博客

一篇就懂:python浅拷贝copy与深拷贝deepcopy_python deepcopy-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

后仿真中 module path polarity 问题

目录 一 未知极性 二 正极性 三 负极性 不知道大家有没有遇到这个问题:什么?我们知道的module path delay 指的是定义在specify...endspecify block 中的语句,指示输入-输出的延迟信息。 这里的module path 竟然还有极性问题,今天,来学习一下。 模块路径的极性是一…

使用dify.ai做一个婚姻法助手

步骤 1:注册并登录 Dify.ai 访问 Dify.ai 官网,注册一个账号并登录。 步骤 2:创建新项目 登录后,点击“创建新项目”。为项目命名,例如“婚姻法助手”。 步骤 3:导入婚姻法文本到知识库 在项目中&…

如何使用idea连接Oracle数据库?

idea版本:2021.3.3 Oracle版本:10.2.0.1.0(在虚拟机Windows sever 2003 远程连接数据库) 数据库管理系统:PLSQL Developer 在idea里面找到database,在idea侧面 选择左上角加号,新建&#xff…

定义和反射Annotation类(注解)

文章目录 前言一、定义Annotation类二、反射Anootation类 1.元注解2.反射注解总结 前言 在写代码的过程中,我们经常会写到注释,以此来提醒代码中的点。但是,这些注释不会被查看,也不在整个代码之中,只能在源代码中进行…

vue 基于antV 实现流程图编辑器代码

最近在做流程图功能开发&#xff0c;发现阿里antV 有对应的可视化引擎&#xff0c;于是自己做了一个简单vue 基于antV 实现流程图编辑器代码 部分代码如下&#xff1a; <template><div id"flowEditorContent"><header><h3>antv X6 流程编辑…

Java热部署:让应用更新如丝般顺滑,告别繁琐重启!

目录 手动启动热部署 自动启动热部署 参与热部署监控的文件范围配置 关闭热部署 什么是热部署&#xff1f;简单说就是你程序改了&#xff0c;现在要重新启动服务器&#xff0c;嫌麻烦&#xff1f;不用重启&#xff0c;服务器会自己悄悄的把更新后的程序给重新加载一遍&…

发那科机器人IO 分配

IO 信号 也称为输入\输出信号&#xff0c;是机器人与外围设备通信的电信号

Studying-代码随想录训练营day16| 513找到左下角的值、112.路径总和、106从中序与后序遍历序列构造二叉树

第十六天&#xff0c;二叉树part03&#x1f4aa;&#x1f4aa;&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 513找到左下角的值 112.路径总和 113.路径总和II 106从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树 总结 513找到左下角的值…

Elk安装及使用

es安装及使用 单机版安装 集群安装 132 node-01 133 node-02 135 node-03 日志用户权限有问题 看日志 解决方案&#xff1a; 出现错误后&#xff0c;再次重启前&#xff0c;需要删除三个节点/data/下的内容 9300-http 9300-tcp logstasha安装及使用 Ssh错误 Yum安装默认路…

职场记 | 有些人的成功真的不是偶然

今天跟大家聊一聊雷总的成长记&#xff0c;希望给职场中的朋友们一点启发&#xff1a; 强烈的创业精神与持续的创新意识 雷军自大学时期起就展现出了强烈的创业热情。他不仅在求学期间积极参与创业活动&#xff0c;更在毕业后迅速踏上创业道路&#xff0c;创立了多家知名企业…

大模型时代,新手和程序员如何转型入局AI行业?

在近期的全国两会上&#xff0c;“人工智能”再次被提及&#xff0c;并成为国家战略的焦点。这一举措预示着在接下来的十年到十五年里&#xff0c;人工智能将获得巨大的发展红利。技术革命正在从“互联网”向“人工智能”逐步迈进&#xff0c;我将迎来新一轮技术革新和人才需求…

NetSuite 不同类型Item的公司间交易科目的设置

我们知道&#xff0c;NetSuite中有Intercompany Preferences的设置&#xff0c;如下所示&#xff0c;分别涉及到公司间应收、公司间应付、公司间收入、公司间费用以及公司间成本共5个科目&#xff0c;非常明确清晰。 最近用户遇到的场景是&#xff0c;如果是Non-Inventory Item…

史上最全的整合Harbor安装教程,哈哈哈哈

一、安装docker 下载地址&#xff1a;https://download.docker.com/linux/static/stable/x86_64/docker-23.0.4.tgz 1.1 解压二进制包 wget https://download.docker.com/linux/static/stable/x86_64/docker-23.0.4.tgz tar zxvf docker-23.0.4.tgz mv docker/* /usr/bin1.2…

【C语言】16.动态内存管理

文章目录 1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free 3.calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存的错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5…

对红酒数据集,分别采用决策树算法和随机森林算法进行分类。

1.导入所需要的包 from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_wine from sklearn.model_selection import train_test_split 2.导入数据&#xff0c;并且对随机森林和决策数进…

每月 GitHub 探索|10 款引领科技趋势的开源项目

1.IT-Tools 仓库名称&#xff1a; CorentinTh/it-tools 截止发稿星数: 16842 (近一个月新增:5744) 仓库语言: Vue 仓库开源协议&#xff1a; GNU General Public License v3.0 引言 CorentinTh/it-tools 是一个开源项目&#xff0c;提供各种对开发者友好的在线工具&#xff0…

教师数字素养标准

老师们有没有想过如何让自己的课堂更加生动、互动&#xff0c;甚至超越传统的教学模式&#xff1f;是否思考过&#xff0c;数字技术如何成为我们教学的得力助手&#xff0c;让我们的课堂焕发出新的活力&#xff1f; 数字素养&#xff0c;这个听起来充满科技感的词汇&#xff0c…

接口实现多态

多态&#xff1a; 父类的引用类型变量指向了子类的对象或者是接口类型的引用类型变量指向了接口实现类 的对象。 实现关系下的多态&#xff1a; 接口 变量 new 接口实现类的对象。 接口 public abstract interface InterA {public abstract void show();}实现类 public c…

文件上传漏洞-上篇

一、概述 文件上传漏洞可以说是日常渗透测试中用得最多的一个漏洞&#xff0c;用它获得服务器权限最快最直接。在web程序中&#xff0c;经常需要用到文件上传的功能。如用户或者管理员上传图片&#xff0c;或者其它文件。如果没有限制上传类型或者限制不严格被绕过&#xff0c…

数据结构6---树

一、定义 树(Tree)是n(n>0)个结点的有限集。当n0时成为空树,在任意一棵非空树中: 1、有且仅有一个特定的称为根(Root)的结点; 2、当n>1时,其余结点可分为m(m>日)个互不相交的有限集T1、T2、...、 Tm&#xff0c;其中每一个集合本身又是一棵树&#xff0c;并且称为根的…