python 2维list_python 可变/不可变对象、+=和=+

fc2a2bb5e86cf956a578bbd3da54e7f1.png

刷lc题的时候,老踩这种坑,索性搞懂。

先有概念:

1、python里面的所有元素都是对象,实例化一个对象就会开辟新的内存空间,然后返回一个引用给你。

2、a = 3。这里实例化了一个对象3,用变量名a表示。需要明确a不是对象本身,a只是这个对象3的引用。(回忆一下c++里面的指针和引用)

可变对象和不可变对象

可变对象和不可变对象的本质区别就是:对象本身的值可不可变。

可变对象:可变对象的值是可以原地 (inplace) 改变的,我们可以通过引用 (变量名) 来操作可变对象,使得它的值原地变化(即不开辟新的内存空间,地址不变)。

包括:list、set、dict(添加值我们不把它看成开辟“新”的内存空间,因为地址没变)。

不可变对象:不可变对象的值是不能改变的。如果引用 (变量名) 如果想要改变值,那不好意思,请你找新的对象去吧!(也就是会实例化新的对象,开辟新的内存空间,产生一个新的地址)

包括:int、str、float、tuple

特殊:int值比较小时[-5,257),会共享对象

Demo(此图出现太多,不明出处):

b17dfb610f855669db2dd3e7bd875c52.png
不可变对象 int

3ecb9bdffa041253b0b36d581fc2c8d2.png
可变对象 list

+= 和 =+

这两个操作符,和可变/不可变对象有密切联系。

+=:调用对象的__iadd__方法,若不存在,才调用__add__方法;

=+:直接调用对象的__add__方法。

__iadd__方法直接在原地 (inplace) 修改对象的值,返回值为None,因此引用的地址不变;而__add__方法会返回一个新的对象,原对象不变。

和可变/不可变对象的联系:

一般情况下,可变对象有__iadd__方法,而不可变对象只有__add__方法。

另:对list而言,+= 和 extend() 等价。

Demo:

0a551382222385ab0785cd3969257a66.png

坑1:python 解二叉树题遇到的问题

坑2:dp初始化二维数组时,下面注释里面那种写法是错的。

class 

为什么呢?因为int是不可变对象,复制出来都是新的对象,所以第一维没有问题。而list复制的只是引用,第二维看似复制了很多次,实际上都指向同一个对象。

所以可以用*复制不可变对象,但千万不要用来复制可变对象!

2492aa68ee12362973067478f40e0dce.png
错误(左),正确(右)

深Copy和浅Copy

这篇文章写得很好,就不重复造轮子了。

张小鸡:5张图彻底理解Python中的浅拷贝与深拷贝​zhuanlan.zhihu.com
028a094a758b8284e055046d4ac7f815.png

总结一下:

1、赋值

赋值操作,其实就是给一段内存地址贴标签。

对于不可变对象,=、copy、deepcopy三者等价。

2、浅拷贝

拷贝父对象的副本,但不会拷贝对象的内部的子对象。

或者说浅拷贝只是拷贝了原始元素的引用(内存地址),拷贝对象的值是否会随着被拷贝对象变化,仅取决于原始元素是可变对象还是不可变对象。

3、深拷贝

完全拷贝了父对象及其子对象。

深拷贝复制的不只是原始元素的引用,而是整个原始元素对象。因此,拷贝对象和被拷贝对象的值相互独立。

参考:

关于python中的+、+=、*、*=
Python 中 a+=b 和 a=a+b 的区别有哪些? - 刘志军的回答 - 知乎
Python中的可变对象与不可变对象
5张图彻底理解Python中的浅拷贝与深拷贝
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值