在網(wǎng)上和學(xué)習(xí)工作中,你可能經(jīng)??吹竭@個(gè)問題,但是依然有很多python
初學(xué)者不了解這個(gè)問題,也不知道為什么這個(gè)問題會(huì)暴露自己是“菜鳥”。這個(gè)問題就是:
“==” 和 “is”之間有什么區(qū)別?
“==”和“is”都是 Python 中的運(yùn)算符。對于初學(xué)者,他們可能會(huì)把“ a==b ”解釋為“ a 等于 b ”,“a is b”也可以解釋為“ a是b ”。這可能就是初學(xué)者在Python
中混淆“ == ”和“ is ”的原因。
在開始之前,我想先展示一些使用“==
”和“is
”的例子。
>>> a = 5
>>> b = 5
>>> a == b
True
>>> a is b
True
很簡單,對吧?a == b
和 a is b
都返回了結(jié)果 True
。接下來我們看另一個(gè)示例:
>>> a = 1000
>>> b = 1000
>>> a == b
True
>>> a is b
False
WTF ??。?從第一個(gè)示例到第二個(gè)示例的唯一變化就是 a 和 b 的值從 5 到 1000。但是返回的結(jié)果在 “==
” 和 “is
” 已經(jīng)不同。我們再看另一個(gè)示例:
>>> a = []
>>> b = []
>>> a == b
True
>>> a is b
False
下面是最后一個(gè)例子,看完是不是覺得自己的腦子要爆炸?
>>> a = 1000
>>> b = 1000
>>> a == b
True
>>> a is b
False
>>> a = b
>>> a == b
True
>>> a is b
True
“==
”的正式運(yùn)算是相等,而“is
”的運(yùn)算是標(biāo)識(shí)。 一般使用“==
”來比較兩個(gè)對象的值。 “ a == b
”應(yīng)解釋為“ a的值是否等于b的值
”。 在上述所有示例中,a 的值始終等于 b 的值(即使對于空列表示例也是如此)。 因此,“a == b
”始終為真。
(推薦教程:python教程)
在解釋身份之前,我需要先介紹id
函數(shù)。 我們可以使用 id
函數(shù)獲得對象的標(biāo)識(shí)。 這個(gè)身份在整個(gè)時(shí)間內(nèi)對于此對象都是唯一且恒定的。此標(biāo)識(shí)在整個(gè)時(shí)間內(nèi)對該對象是唯一且不變的。你可以把它看作是這個(gè)對象的地址。如果兩個(gè)對象具有相同的標(biāo)識(shí),則它們的值也必須相同。
>>> id(a)
2047616
運(yùn)算符“ is
”是比較兩個(gè)對象的標(biāo)識(shí)是否相同。“a is b
”的意思是“a的身份與b的身份相同
”。
如果你知道“ ==
”和“ is
”的實(shí)際含義,我們就可以開始研究上面的幾個(gè)示例了。
首先是第一個(gè)和第二個(gè)示例中的結(jié)果不同。 顯示不同結(jié)果的原因是Python
存儲(chǔ)了一個(gè)介于-5到256之間的整數(shù)的數(shù)組列表,每個(gè)整數(shù)具有固定的標(biāo)識(shí)。當(dāng)我們在此范圍內(nèi)分配整數(shù)變量時(shí),Python
會(huì)將此變量的標(biāo)識(shí)分配為數(shù)組列表內(nèi)整數(shù)的整數(shù)。 結(jié)果,對于第一個(gè)示例,由于a
和b
的標(biāo)識(shí)都是從數(shù)組列表中獲得的,因此它們的標(biāo)識(shí)當(dāng)然是相同的,因此 “a is b
” 為True
。
>>> a = 5
>>> id(a)
1450375152
>>> b = 5
>>> id(b)
1450375152
但是一旦該變量的值超出該范圍,由于 Python
內(nèi)部沒有具有該值的對象,因此Python
將為此變量創(chuàng)建一個(gè)新的標(biāo)識(shí)并將該值分配給該變量。 如前所述,身份對于每個(gè)創(chuàng)建都是唯一的,因此,即使兩個(gè)變量的值相同,其身份也永遠(yuǎn)不會(huì)相等。 這就是為什么“a is b
”在第二個(gè)例子結(jié)果為False
。
>>> a = 1000
>>> id(a)
12728608
>>> b = 1000
>>> id(b)
13620208
PS:如果你打開了兩個(gè)控制臺(tái),該值仍在該范圍內(nèi),那么你將獲得相同的標(biāo)識(shí)。但是,如果該值不在該范圍內(nèi),則結(jié)果就會(huì)發(fā)生改變。
如果你理解了第一示例和第二示例之間的區(qū)別,就很容易理解第三示例的結(jié)果。由于 Python
不存儲(chǔ)“空列表”對象,因此 Python
創(chuàng)建了一個(gè)新對象并分配了“空列表”值。無論兩個(gè)列表為空還是元素相同,結(jié)果都是相同的。
>>> a = [1,10,100,1000]
>>> b = [1,10,100,1000]
>>> a == b
True
>>> a is b
False
>>> id(a)
12578024
>>> id(b)
12578056
接下來,我們轉(zhuǎn)到最后一個(gè)示例。第二個(gè)和最后一個(gè)示例之間的唯一區(qū)別是還有一行代碼 a = b
,正是這行代碼改變了變量 a 的命運(yùn)。以下結(jié)果將告訴你真實(shí)原因:
>>> a = 1000
>>> b = 2000
>>> id(a)
2047616
>>> id(b)
5034992
>>> a = b
>>> id(a)
5034992
>>> id(b)
5034992
>>> a
2000
>>> b
2000
如上所示,在 a = b
之后,a 的身份更改為 b 的身份。a = b
將 b 的身份分配給 a 。因此 a 和 b 具有相同的標(biāo)識(shí),因此 a 的值現(xiàn)在與 b 的值相同(即2000)。
(推薦微課:python3基礎(chǔ)微課)
最后一個(gè)示例告訴我們一個(gè)重要消息,即我們可能會(huì)無意中更改對象的值,而不會(huì)事先通知,尤其是當(dāng)對象是列表時(shí)。
>>> a = [1,2,3]
>>> id(a)
5237992
>>> b = a
>>> id(b)
5237992
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
在上面的示例中,由于 a 和 b 具有相同的標(biāo)識(shí),因此它們的值必須相同。 所以,在將新元素添加到 a 之后,b 的值也會(huì)受到影響。為避免這種情況,如果要將值從一個(gè)對象復(fù)制到另一個(gè)對象而不引用相同的標(biāo)識(shí),則所有方法之一是在 copy
模塊中使用 deepcopy
。 對于列表,我們還可以通過 b = a [:]
執(zhí)行。
>>> import copy
>>> a = [1,2,3]
>>> b= copy.deepcopy(a)
>>> id(a)
39785256
>>> id(b)
5237992
使用[:]
將元素復(fù)制到新變量。
>>> a = [1,2,3]
>>> id(a)
39785256
>>> b = a[:]
>>> id(b)
23850216
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]
以上就是關(guān)于“==”和“is”有什么區(qū)別?的相關(guān)內(nèi)容了,看完這些是不是覺得已經(jīng)充分了解兩者之間的區(qū)別。以后面試遇到這種問題,可別答錯(cuò)咯。