对python中比较操作符(==)和同一性运算符(is)的进一步理解

对python中比较操作符(==)和同一性运算符(is)的进一步理解

知识改变命运

比较操作符和同一性运算符

Python中有很多运算符,今天我们就来讲讲is和==两种运算符在应用上的本质区别是什么。

在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。

is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。下面来看看具体区别在哪。

==比较操作符和is同一性运算符区别

==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等,例如下面两个字符串间的比较:

a = 'cheesezh'
b = 'cheesezh'
a == b
#True

is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。通过对下面几个list间的比较,你就会明白is同一性运算符的工作原理:

x = y = [4,5,6]
z = [4,5,6]
x == y
#True

x == z
#True

x is y
#True

x is z
#False

为什么最后一个是False呢?x、y和z的值是相同的,所以前两个是True没有问题。至于最后一个为什么是False,看看三个对象的id分别是什么就会明白了。

print id(x)
#3075326572
print id(y)
#3075326572
print id(z)
#3075328140

只有数值型和字符串型的a == b情况下,a is b才为True,当a == b是tuple,list,dict或set型时,a is b为False。

事实上Python 为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。而Python 对小整数的定义是 [-5, 257),只有数字在-5到256之间它们的id才会相等,超过了这个范围就不行了,同样的道理,字符串对象也有一个类似的缓冲池,超过区间范围内自然不会相等了。

总的来说,只有数值型和字符串型,并且在通用对象池中的情况下,a is b才为True,否则当a和b是int,str,tuple,list,dict或set型时,a is b均为False。

如果创建a = 255,b = 255,c = 257, d = 257的话,他的变量指向如下所示:

创建在小整数对象池中的对象时,直接指向小整数对象池的特定值,而要创建不在小整数对象池中的数据时需要实时创建,并且每一个变量值只能被一个变量指向。

也就是要创建两个变量值为257的变量,需要创建两个值为257的对象,而创建两个变量值为255的变量,只是将两个变量名指向在小整数对象池中的255

换句话说,就是 a is b是正确的,而c is d是错误的,当然a==b,c==d都是正确的。

驻留机制

字符串驻留机制

对于短字符串,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副 本。长字符串不遵守驻留机制。

驻留适用范围

由数字,字符和下划线(_)组成的python标识符以及整数[-5,256]。

str1='stenwaves'
str2='stenwaves'
str1 is str2
# True
id(str1)
# 2072034398512
id(str2)
# 2072034398512
str3='sten waves'
str4='sten waves'
str3 is str4
# False
id(str3)
# 2072034399920
id(str4)
# 2072034399856

看得出来非数字,字符和下划线(_)组成的字符串并不会触发驻留。python中用is可以比较两个字符串是否是同一个对象,也就是内存地址是否一样。

驻留时机

python中的驻留发生在编译时间,而不是运行时间

str1='sten'+'waves'
str2 is 'stenwaves'
# True
str3='sten'
str4=str3+'waves'
str4 is 'stenwaves' 
# False

优缺点

  1. python标识符的不可变性导致了字符串的改动不是采用replace,而是重新创建对象。为了节省内存,涉及到字符串的改动时通常用join()而非+。因为+会多次创建对象,而join()只创建一次对象。
  2. 驻留机制会提升一些时间和空间上的性能,但驻留对象也有所消耗。

参考文献:

浅析python 数据存储原理&深拷贝&浅拷贝&is ==

Python中的字符串驻留机制
对python中比较操作符(==)和同一性运算符(is)的进一步理解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章