参考博客

引言

python里的变量对象包括不可变对象(int,float,long,str,tuple等),和可变对象(list,set,dict等)。对于这两种对象的赋值和拷贝问题是和其它语言有差别的,不加分辨地使用容易出错。

浅复制问题

不可变对象(int,float,long,str,tuple等)其实是标签,类似于c语言里的指针。例如对于int类型的对象a,a=10是把a贴到10这个数上了,而a=20是把a从10上撕下来,拿去贴到20上面了。因此a=10后执行a=20,a地址会变

a = 10
print(id(a))
a = 20
print(id(a))

结果如下,地址值可能会不一样,看你的python解释器的分配情况,我们只要比较前后地址值的改变与否即可,下同。

140725279137824
140725279138144

并且,除了a=a这个情况,a的地址不会变,哪怕是a=10.0(float型),a=2a-a,这么处理之后的a地址也会变(不过当a是int的时候,a=2a-a地址不变,但是a=0.5a+0.5a地址会变,因此猜测是解释器的优化原因)

a = 10.0
print(id(a))
a = 0.5*a+0.5*a
print(id(a))

结果

2159059426256
2159059426320

这种直接用等于号赋值只是贴标签,叫做浅复制,就是不是把a的值拷贝到b,而是让a和b都指向同一个值,这样子会出现一些问题。例如在列表赋值时,values并没有出现[0,[0,1,2],2]这种情况,而是出现了循环嵌套。这是因为values[1]的标签贴到了原来的values上,于是在检索values[1]的时候就跳到values[0],接着往下走values[1],然后继续循环。

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

结果

2579107863680
2579107863680
[0, [...], 2]

而直接用values[:]貌似可以解决这个问题

values = [0, 1, 2]
print(id(values))
values[1] = values[:]
print(id(values))
print(values)

结果

2366984019008
2366984019008
[0, [0, 1, 2], 2]

但是values[:]只是复制顶层,如果出现数组嵌套就还是会出现错误情况,可见于
这篇博客
还有一点需要注意的是,a=a+a和a+=a是不一样的,后者是原地复操作。例如对于列表,就是在它之后继续加元素,但是列表头的地址不变

a = [10];
print(id(a))
a = a+a;
print(id(a))
print(a)
b = [10];
print(id(b))
b += b;
print(id(b))
print(b)

结果

1716028562560
1716033074112
[10, 10]
1716033074240
1716033074240
[10, 10]

但是对于int等变量的值,原地操作仍然会改变地址值。这还是因为贴标签的原因。python存了个10,然后把a贴上去,但是a+a=20,所以python开了个存储空间放20,把a标签撕下来贴到20上面了。这时候再b=10,就是把b贴到10上,因此这时b的地址和最开始a的地址是一样的。

a = 10;
print(id(a))
a = a+a;
print(id(a))
print(a)
b = 10;
print(id(b))
b += b;
print(id(b))
print(b)

结果

140725279137824
140725279138144
20
140725279137824
140725279138144
20

深复制问题

深复制可以用copy 模块的 deepcopy 方法,具体可以看[这个](copy 模块的 deepcopy 方法)

Python的变量指向和引用问题、赋值和拷贝问题相关推荐

  1. python中变量的地址引用和拷贝

    python中变量的地址引用和拷贝 最近在自学python,看官方文档的时候被copy弄懵了,所以恶补了一下关于变量到底是怎么回事的知识,总结一下自己思考和参考其他文章的内容,此篇作为备忘录(岁数大了 ...

  2. python中变量无须先创建和赋值而直接使用_python综合练习1

    客观题和第五大题写在答题卡.txt中,其他题目请提交题号.py程序 Python综合练习1 一.填空题 1.Python使用符号标示注释. 2.可以使用符号把一行过长的Python语句分解成几行. 3 ...

  3. python是值传递还是引用传递_Python里参数是值传递还是引用传递?

    Python就是把一些参数从一个函数传递到另一个函数,从而使其执行相应的任务.但是你有没有想过,参数传递的底层是如何工作的,原理又是怎样的呢? 实际工作中,很多人会遇到这样的场景:写完了代码,一测试, ...

  4. python中、变量指向的对象可以发生变化吗_python中的引用传递,可变对象,不可变对象,list注意点...

    python中的引用传递 首先必须理解的是,python中一切的传递都是引用(地址),无论是赋值还是函数调用,不存在值传递. 可变对象和不可变对象 python变量保存的是对象的引用,这个引用指向堆内 ...

  5. python 变量传值传引用 区分

    传值:strings tuples numbers 传引用: list dict python的变量都可以看成是内存中某个对象的引用.(变量指向该内存地址存储的值) 1.python中的可更改对象和不 ...

  6. python定义变量并赋值_Python 变量类型及变量赋值

    在 Python 中,变量不一定占用内存变量.变量就像是对某一处内存的引用,可以通过变量访问到其所指向的内存中的值,并且可以让变量指向其他的内存.在 Python 中,变量不需要声明,但是使用变量之前 ...

  7. 【Python】Python中的引用和赋值

    本文转自:http://my.oschina.net/leejun2005/blog/145911 在 python 中赋值语句总是建立对象的引用值,而不是复制对象.因此,python 变量更像是指针 ...

  8. python释放变量内存_Python尚学堂高淇|1113引用的本质栈内存,堆内存,内存的示意图,标识符,变量的声明初始化,垃圾回收机制...

    011-引用的本质-栈内存和堆内存-内存的示意图在Python当中,变量也成为:对象的引用,因为,变量的存储就是对象的地址变量通过地址引用了对象变量位于堆内存(压栈,出栈等细节,后续再介绍)对象位于: ...

  9. python赋值语句对错_深入理解Python中变量赋值的问题

    前言 在Python中变量名规则与其他大多数高级语言一样,都是受C语言影响的,另外变量名是大小写敏感的. Python是动态类型语言,也就是说不需要预先声明变量类型,变量的类型和值在赋值那一刻被初始化 ...

最新文章

  1. 快速提升UI设计感的7个版式小妙招
  2. 附录C 编译安装Hive
  3. 在Hadoop集群实施成功后再次格式化名称节点,datanode无法加入集群的处理办法
  4. SpringMVC中RestFul风格
  5. 因为CSS文件编码问题IE6无法正确解析CSS
  6. [OpenS-CAD]屏幕坐标转换分析
  7. atm取款流程测试_盘点2020年软件测试新手必看的技术面试指南(下)
  8. IEEE745浮点数格式
  9. 樊登读书会掌控读后感_樊登读书会观后感
  10. python实现自定义搜索内容的天眼查爬虫
  11. 个人网站如何申请支付接口?(教程)
  12. launch 文件解析
  13. Aid Learning --除了爱奇艺也可以是生产力!!!
  14. cannot import name ‘utc‘
  15. 【广度优先搜索】leetcode 994. 腐烂的橘子
  16. oCPC实践录 | 广告冷启动问题的思考与总结
  17. 建立图书馆书目索引表
  18. Java:文件写入读取操作和工具类
  19. 英特尔眼中的三大科技趋势
  20. python开发实例-python开发案例

热门文章

  1. opencv 简单美颜效果
  2. VR技术类毕业论文文献有哪些?
  3. 互联网创业大方向就两点:信息本身更对称+市场价格更低廉
  4. 【程序员基础必备】计算机组成原理概念大全
  5. python学习 2
  6. 中国移动一键免密登录 103101签名错误
  7. 云南林业计算机单招试题,云南林业职业技术学院2020年单招考试时间与地点
  8. Day 4 Data Flow Analysis-Foundations
  9. JAVA core foundations
  10. 2014 usnews 计算机科学 排名 天道留学,2014年美国USNews计算机专业研究生大学排名...