Python学习:Python对象的比较、拷贝

在写python代码时,经常用到 Python 对象比较和复制的语句,但语句背后发生了什么,总是不清楚。
举一些用到的例子:
判断a和b是否相等的例子:

if a == b:
    ...

两个列表之间的拷贝,l2 就是 l1 的拷贝。

l1 = [1, 2, 3]
l2 = list(l1)

其中a == b是比较两个对象的值相等,还是两个对象完全相等呢?

l2 是 l1 的浅拷贝(shallow copy)还是深度拷贝(deep copy)呢?

一、比较’==’ VS ‘is’

等于(==)== 和 is 是 Python 中对象比较常用的两种方式。
简单来说,’=='操作符比较对象之间的值是否相等,比如下面的例子,表示比较变量 a 和 b 所指向的值是否相等。

a==b

而’is’操作符比较的是对象的身份标识是否相等,即它们是否是同一个对象,是否指向同一个内存地址

在 Python 中,每个对象的身份标识,都能通过函数 id(object) 获得。因此,'is’操作符,相当于比较对象之间的 ID 是否相等,我们来看下面的例子:

a = 10
b = 10 

a == b
True

id(a)
4427562448 

id(b)
4427562448

a is b
True

首先 Python 会为 10 这个值开辟一块内存,然后变量 a 和 b 同时指向这块内存区域,即 a 和 b 都是指向 10 这个变量,因此 a 和 b 的值相等,id 也相等,a == b和a is b都返回 True。

注意:课程中讲到 -5 到 256 范围内的数字,超过范围会a is b返回了 false,但实验结果并不都是这样的。

课中:对于整型数字来说,以上a is b为 True 的结论,只适用于 -5 到 256 范围内的数字。比如下面这个例子:

a = 257
b = 257 

a == b
True

id(a)
4473417552

id(b)
4473417584

a is b
False

把 257 同时赋值给了 a 和 b,可以看到a == b仍然返回 True,因为 a 和 b 指向的值相等。但奇怪的是,a is b返回了 false,并且我们发现,a 和 b 的 ID 不一样了.

事实上,出于对性能优化的考虑,Python 内部会对 -5 到 256 的整型维持一个数组,起到一个缓存的作用。这样,每次你试图创建一个 -5 到 256 范围内的整型数字时,Python 都会从这个数组中返回相对应的引用,而不是重新开辟一块新的内存空间。

但是,如果整型数字超过了这个范围,比如上述例子中的 257,Python 则会为两个 257 开辟两块内存区域,因此 a 和 b 的 ID 不一样,a is b就会返回 False 了。

实验:(pycharm中)

a = 257
b = 257
print(id(a))
print(id(b))
print(a == b)
print(a is b)

1871680969872
1871680969872
True
True

但在命令行中输入确实是False,标识也不相同:
在这里插入图片描述

在实际工作中,当我们比较变量时,使用’==‘的次数会比’is’多得多,因为我们一般更关心两个变量的值,而不是它们内部的存储地址。但是,当我们比较一个变量与一个单例(singleton)时,通常会使用’is’。一个典型的例子,就是检查一个变量是否为 None:

if a is None:
      ...

if a is not None:
      
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值