原創(chuàng)| Python中"等于"到底用 == 還是 is ?
?大家好,我是寶器。
最近有讀者問我一道面試題,希望我能夠詳細的寫一寫相關的內(nèi)容,這不,馬上安排!
is 和 == 的區(qū)別
看上去其實很簡單,但是其中也有很多的細節(jié),今天這篇文章就是帶著大家來深入了解相關的知識。
舉幾個例子
如果一開始就解釋,那么肯定很多小伙伴不會理解,所以我們先跑幾個程序。
>>>?x?=?y?=?[4,3,1]
>>>?z?=?[4,3,1]
>>>?print(x?is?y)
True
>>>?print(x?==?y)
True
>>>?print(x?==?z)
True
>>>?print(x?is?z)
False
首先我們來看看這個例子,我們會發(fā)現(xiàn)x不管是使用 is 還是 == 都返回True,但是x,z的內(nèi)容一樣,使用 == 返回的True,但是使用 is 時候返回卻是False。
在Python中,== 比較的是值,is 比較的是對象。
其中Python對象中主要包含id、值以及數(shù)據(jù)類型,在is的比較中比較的是id。
所以這里我們再打印一下x、y、z三者的id值
>>>?print(id(x))
140513337973408
>>>?print(id(y))
140513337973408
>>>?print(id(z))
140513337973248
通過比較x與y的id值是相等的,但是z的id值就不同了。
為什么x與y是相同的呢?
在Python中,= 不僅僅只是賦值,它還會將引用地址也賦過去,所以在內(nèi)存中,x和y調(diào)用的是同一個對象。
大家可以參照下圖

我們接下來繼續(xù)看
>>>?a?=?'123'
>>>?b?=?'123'
>>>?print(a?is?b)
True
>>>?print(a?==?b)
True
##############
>>>?c?=?100
>>>?d?=?100
>>>?print(c?==?d)
True
>>>?print(c?is?d)
True
##############
>>>?a?=?1000
>>>?b?=?1000
>>>?print(a?is?b)
False
>>>?print(a==b)
True
看到這里可能有些朋友就迷惑了,這...是啥?
首先我來說下字符串為什么會相等,其實在python中存在一個intern機制,這個機制中值同樣的字符串對象僅僅會保存一份,這樣做是為了提高Python的運行效率。
那么它是怎么實現(xiàn)的呢?其實很簡單,這個intern機制就是通過維護字符串儲蓄池(一個字典)來運作的,這個字典的key是字符串的值,value則是這個字符串的引用地址。
每次當你創(chuàng)建一個新的字符串時,都會去該字符串儲蓄池查找,是否有相同的字符串值,如果存在則直接調(diào)用該字符串的引用地址。
相信你看到這,已經(jīng)明白字符串為什么會一直相等了。

接下來我們繼續(xù)聊聊下面兩個整型的比較,這個更讓我們迷惑了。
>>>?c?=?100
>>>?d?=?100
>>>?print(c?==?d)
True
>>>?print(c?is?d)
True
##############
>>>?a?=?1000
>>>?b?=?1000
>>>?print(a?is?b)
False
>>>?print(a==b)
True
其實也并不難理解,在python中有小整數(shù)對象池的概念,小整數(shù)對象池簡單來說就是在[-5,256]這個區(qū)間內(nèi)創(chuàng)建的對象,不會被回收。
也就是說,當你創(chuàng)建了一個整數(shù)在[-5,256]這個區(qū)間內(nèi)時,它會先去查看是否有相同的值,如果有則直接引用該地址。
如果你創(chuàng)建的不是在這個區(qū)間內(nèi),那么它會重新創(chuàng)建一個新的對象,所以它的地址肯定也就不同了。
總結(jié):在Python中,只有小整數(shù)對象池中和字符串會調(diào)用已經(jīng)存在的地址,其他的像list,tuple,dict都會重新創(chuàng)建一個新的對象。
總結(jié)
在Python中,is 和 == 還是有一些區(qū)別的,我們不能隨意的去使用它。
但是現(xiàn)在我們編寫代碼基本都是在IDE上,例如pycharm,在pycharm中它對解釋器進行了優(yōu)化,不管你的值是否在區(qū)間[-5,256]中,只要值相等那么他們兩就會完全相等。所以這里需要特別注意。
OK,以上就是今天的文章,我們下期再見!
