R语言 C语言 Apache datetime canvas boost ssh tfs printing webforms Vanilla JS android项目实战 edate函数的使用方法 maven插件 matlab图像滤波 linux启动mysql命令 网页设计公司 python的开发工具 python基础代码 java编程环境 javase教程 java方法 javaworld 微信客户管理系统 两表关联查询 思源黑体cn 卡巴斯基离线升级包 微信彩色字 sim卡注册失败 变声器电脑版 淘宝抽奖活动 画图3d 巫师3福利 android计算器 服务器系统安装教程 js观察者模式 cdr快捷键设置 ps怎么把人p瘦 劲舞团辅助 标准色
当前位置: 首页 > 学习教程  > 编程学习

python:可变or不可变类型,深浅拷贝

2021/1/9 2:04:43 文章标签: 深浅拷贝

原文地址:http://www.cnblogs.com/huamingao/p/5809936.html 可变类型 Vs 不可变类型 可变类型(mutable):列表,字典 不可变类型(unmutable):数字,字符串,元组…

原文地址:http://www.cnblogs.com/huamingao/p/5809936.html

可变类型 Vs 不可变类型

可变类型(mutable):列表,字典

不可变类型(unmutable):数字,字符串,元组

这里的可变不可变,是指内存中的那块内容(value)是否可以被改变

 

代码:


 
name1='wupeiqi'
name2=name1
print("name1:%s\nname2:%s" %(name1,name2))
name1='alex'
print("I have assigned new value to name1.Let's see what happens to name2!")
print("name1:%s\nname2:%s" %(name1,name2))</pre>

执行结果:


C:/Personal/OldboyPython/day01/test.py
name1:wupeiqi
name2:wupeiqi
I have renamed name1 to new_name.Let's see what happens!
name1:alex
name2:wupeiqi</pre>

疑问:为什么name2的值没有和name1一起变为alex?下面开始解答,先看图,后解释。

 

以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

变量的赋值


  
#!/usr/bin/env python
# -*- coding: utf-8 -*-
name1 = "wupeiqi"
name2 = "alex"</pre>
 

  
#!/usr/bin/env python
# -*- coding: utf-8 -*-

name1 = "wupeiqi"   
name2 = name1     # 使name2和name1指向同一个对象 <strong>赋值</strong>,只是创建一个变量,该变量指向原来内存地址,</pre>
 以上引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html
 

1.引用计数的增减

当对象wupeiqi(图中蓝色的内存区块wupeiqi)被初次创建并(将其引用)赋值给变量name1时,对象wupeiqi的引用计数被设置为1。

当对象alex(图中蓝色的内存区块alex)被初次创建并(将其引用)赋值给变量name2时,对象alex的引用计数被设置为1。

当变量name1赋值给变量name2(name2=name1),实际是把对象wupeiqi赋值给name2,因此对象wupeiqi的引用计数自动加1,而对象alex的引用计数自动减1,即减为0,触发垃圾回收机制。

2. 可变类型 Vs 不可变类型

可变类型(mutable):列表,字典

不可变类型(unmutable):数字,字符串,元组

这里的可变不可变,是指内存中的那块内容(value)是否可以被改变。如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请一块区域(因为老区域#不可变#)。如果是可变类型,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的address会保持不变,但区域会变长或者变短。

可以使用内建函数id()来确认对象的身份在两次赋值前后是否发生了变化。示例可参看http://blog.chinaunix.net/uid-26249349-id-3080279.html

*不可变类型有什么好处?如果数据是不可变类型,当我们把数据传给一个不了解的API时,可以确保我们的数据不会被修改。如果我们要操作一个从函数返回的元组,可以通过内建函数list()把它转换成一个列表。(当被问到列表和元组的区别时,可以说这一点!)

3. 深拷贝 Vs 浅拷贝

copy.copy() 浅拷贝

copy.deepcopy() 深拷贝

浅拷贝是新创建了一个跟原对象一样的类型,但是其内容是对原对象元素的引用。这个拷贝的对象本身是新的,但内容不是。拷贝序列类型对象(列表\元组)时,默认是浅拷贝。

 

 以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

赋值,只是创建一个变量,该变量指向原来内存地址,如下例:

n4 = n3 = n2 = n1 = "123/'Wu'"

关于赋值,再看一个字典的例子:


n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1</pre>

 浅拷贝,在内存中只额外创建第一层数据,如下图


import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n3 = copy.copy(n1)</pre>

深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化),如下图:


import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n4 = copy.deepcopy(n1)</pre>


本文链接: http://www.dtmao.cc/news_show_1100276.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?