copy和deepcopy[通俗易懂]

copy和deepcopy[通俗易懂]总结一下,如果一个集合中的元素是字符串,copy之后则是两个互不相干的新集合,内存地址也不一样,修改任意一个另一个不会做出改变,但是如果其中的元素有数组的话,那么情况就不一样了,copy后虽然集合是两个完全新的集合,但是集合中的数组指向的是同一个内存地址,在此集合中对其中的数组数据进行修改,另一个集合中的元素是数组的内容也会改变,如果想完完全全独立出来是两个独立的集合,就得使用deepcopy而不…

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

Jetbrains全系列IDE稳定放心使用

总述

先说明一下,这是python中用来表示复制的概念

总结一下:

如果一个集合中的元素是字符串,copy之后则是两个互不相干的新集合,内存地址也不一样,修改任意一个另一个不会做出改变

但是如果其中的元素有数组的话,那么情况就不一样了

copy后虽然集合是两个完全新的集合,但是集合中的数组指向的是同一个内存地址,在此集合中对其中的数组数据进行修改,另一个集合中的元素是数组的内容也会改变

如果想完完全全独立出来是两个独立的集合,就得使用deepcopy而不是copy

仔细品

如果你够聪明听懂了,就可以关掉文章去耍了(使用方式在之后)

否则看以下操作实例

操作实例

看 仔 细 一 点

·> > > x = {" name":" qiwsir", "lang":[" python", "java", "c"]} 

·> > > y = x.copy() 

·> > > y {' lang': [' python', 'java', 'c'], 'name': 'qiwsir'} 

·> > > id( x) 3072241012L 

·> > > id( y) 3072241284L 

y 是 从 x 拷 贝 过 来 的, 两 个 在 内 存 中 是 不 同 的 对 象。

·> > > y[" lang"]. remove(" c") 

在 y 所 对 应 的 字 典 对 象 中, 键” lang” 的 值 是 一 个 列 表, 为[’ python’,’ java’,’ c’], 这 里 用 remove() 删 除 其 中 的 一 个 元 素” c”。 删 除 之 后, 这 个 列 表 变 为:[’ python’,’ java’]。

·> > > y 

{' lang': [' python', 'java'], 'name': 'qiwsir'}

那 么, x 所 对 应 的 字 典 中, 这 个 列 表 变 化 了 吗? 应 该 没 有 变 化, 因 为 按 照 前 面 所 讲 的, 它 是 另 外 一 个 对 象, 两 个 互 不 干 扰。

·> > > x 

{' lang': [' python', 'java'], 'name': 'qiwsir'}

仔 细 观 察, 是 不 是 有 点 出 乎 意 料 呢? 我 没 有 作 弊 哦。 如 果 不 信, 就 按 照 操 作 自 己 在 交 互 模 式 中 试 试, 是 不 是 也 能 够 得 到 这 个 结 果 呢? 这 是 为 什 么? 但 是, 如 果 要 操 作 另 外 一 个 键 值 对:

·> > > y[" name"] = "laoqi" 

·> > > y 

{' lang': [' python', 'java'], 'name': 'laoqi'} 

·> > > x 

{' lang': [' python', 'java'], 'name': 'qiwsir'} 

前 面 所 说 的 原 理 是 有 效 的, 为 什 么 当 值 是 列 表 的 时 候 就 不 奏 效 了 呢? 要 破 解 这 个 迷 局 还 得 用 id():

·> > > id( x) 3072241012L 

·> > > id( y) 3072241284L

x 和 y 对 应 着 两 个 不 同 的 对 象, 的 确 如 此。 但 这 个 对 象( 字 典) 是 由 两 个 键 值 对 组 成 的, 其 中 一 个 键 的 值 是 列 表。

·> > > id( x[" lang"]) 3072243276L 

·> > > id( y[" lang"]) 3072243276L 

发 现 了 这 样 一 个 事 实: 列 表 是 同 一 个 对 象。 但 是, 作 为 字 符 串 为 值 的 那 个 键 值 对 分 属 不 同 的 对 象。

·> > > id( x[" name"]) 3072245184L

·> > > id( y[" name"]) 3072245408L 

解释分析

这 个 事 实 就 说 明 了 为 什 么 修 改 一 个 列 表, 另 外 一 个 也 跟 着 修 改; 而 修 改 一 个 字 符 串, 另 外 一 个 不 跟 随 的 原 因 了。

但 是, 似 乎 还 没 有 解 开 深 层 的 原 因。 深 层 的 原 因 与 Python 存 储 的 对 象 类 型( 在 不 少 地 方 也 用“ 数 据 类 型” 的 说 法, 其 实 两 者 是 一 样 的,“ 对 象” 和“ 数 据” 在 Python 中 等 同, 不 用 区 分) 特 点 有 关, Python 只 存 储 基 本 类 型 的 数 据, 比 如 int、 str, 对 于 不 是 基 础 类 型 的, 比 如 字 典 的 值 是 列 表, Python 不 会 在 被 复 制 的 那 个 对 象 中 重 新 存 储, 而 是 用 引 用 的 方 式, 指 向 原 来 的 值。

通 俗 地 说, Python 在 所 执 行 的 复 制 动 作 中, 如 果 是 基 本 类 型 的 数 据, 就 在 内 存 中 重 新 建 个 窝, 如 果 不 是 基 本 类 型 的, 就 不 新 建 窝 了, 而 是 用 标 签 引 用 原 来 的 窝。

即 如 果 比 较 简 单, 随 便 建 立 新 窝 即 可; 但 是, 如 果 对 象 太 复 杂 了, 就 别 费 劲 了, 还 是 引 用 一 下 原 来 的 省 事。

所 以, 把 用 copy() 实 现 的 拷 贝 称 之 为“ 浅 拷 贝”( 不 仅 Python, 很 多 语 言都 有“ 浅 拷 贝”。 顾 名 思 义, 没 有 解 决 深 层 次 问 题。 言 外 之 意, 还 有 能 够 解 决 深 层 次 问 题 的 方 法)。

与“ 浅 拷 贝” 对 应, 在 Python 中, 还 有 一 个“ 深 拷 贝”( deep copy)。 不 过, 要 用 import 导 入 一 个 模 块。

deepcopy使用方式

·> > > import copy 

·> > > z = copy.deepcopy( x)

·> > > z 

{' lang': [' python', 'java'], 'name': 'qiwsir'} 

用 copy.deepcopy() 深 拷 贝 了 一 个 新 的 副 本, 用 id() 来 勘 察 一 番:

·> > > id( x[" lang"]) 

3072243276L 

·> > > id( z[" lang"]) 

3072245068L

果 然 是 另 外 一 个“ 窝”, 不 是 引 用 了。 如 果 按 照 这 个 结 果, 修 改 其 中 一 个 列 表 中 的 元 素, 应 该 就 不 影 响 另 外 一 个 了。

·> > > x 

{' lang': [' python', 'java'], 'name': 'qiwsir'} 

·> > > x[" lang"]. remove(" java") 

·> > > x 

{' lang': [' python'], 'name': 'qiwsir'}

·> > > z 

{' lang': [' python', 'java'], 'name': 'qiwsir'} 

果 然 如 此, 再 试 试 才 过 瘾 呀。

·> > > x[" lang"]. append(" c + +") 

·> > > x {' lang': [' python', 'c + +'], 'name': 'qiwsir'} 

这 就 是 所 谓 的 浅 拷 贝 和 深 拷 贝。

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

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

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

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

(0)


相关推荐

  • Java反射机制:跟着代码学反射

    Java反射机制:跟着代码学反射微信搜索:码农StayUp主页地址:https://gozhuyinglong.github.io源码分享:https://github.com/gozhuyinglong/blog-demos1.前言在OOP的世界里,万物皆对象。也就是说,我们可以将任何东西抽象成一个对象。比如人,可以抽象成一个Person类,通过newPerson()来实例化一个对象;再比如鸭子,可以抽象成一个Duck类,也可以对其进行实例化……那么这一个个类本身是不是也可以抽象成一个类呢?Java提供了一个特殊的类..

  • 两款实用的DDos攻击工具[通俗易懂]

    两款实用的DDos攻击工具[通俗易懂]两款实用的DDos攻击工具2018-02-22Network•Security865之前为了重现某个bug,需要对网络设备进行ddos攻击测试,同时也是对设备的网络攻击防护功能进行抗压测试。临阵磨枪,google了两款攻击工具,windows平台的hyenae,以及Linux平台的hping3,在此记录一下两者的用法。Hyenaehyenae是在Windows平台上非常好用的一…

  • [转][darkbaby]任天堂传——失落的泰坦王朝(下)[通俗易懂]

    [转][darkbaby]任天堂传——失落的泰坦王朝(下)[通俗易懂]即使是日本业界人士也对1999年发生的“口袋妖怪所有权风波”知之甚少,实际上这个事件的结局足以改变游戏产业未来数十年的势力图,山内溥凭借着个人的睿智让任天堂再次渡过了命运的暗礁,而另一颗曾经炙手可热的璀璨明星却从此销声匿迹……   株式会社POKEMON(简称TPC)成立于1998年4月,由任天堂、Creatures、GAMEFREAK三社共同出资组建,该社成立的目的主要是对全球范围的口…

  • 【软件工具】服务器硬件资源监控

    【软件工具】服务器硬件资源监控服务器资源使用情况及硬件监控,是服务器管理员或运维人员必备的技能和工作内容。对于服务器硬件的时时监控,除了需要掌握定的方法外,还常会用到些相应的相关软件程序。当然,运维同仁般都具备定的编程能力,根据服务器情况,编写个便捷、好用和适合自己的服务器硬件监控软件也是很有必要的。     服务器硬件监控常用方法及相关软件:  raid卡监控:raid卡常有rai

  • 关于Android导航页开发的体会

    关于Android导航页开发的体会2019独角兽企业重金招聘Python工程师标准>>>…

  • 保研面试/考研复试:英语口语面试必备话题及常用句型句式整理(二)「建议收藏」

    目录TravelAFFIRMATIVENEGATIVEArtFORAGAINSTShoppingAFFIRMATIVENEGATIVEPetAFFIRMATIVENEGATIVETravelAFFIRMATIVEWecanexplorenewplacesandmeetnewfolks.Iprefertotravellight.PeoplefromallwalksoflifeenjoytravellingTravelingwithfriendsisa

发表回复

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

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