Python 技巧3:對(duì)象比較:“is” vs “==”
這篇文章由偉兄整理供稿。另外,歡迎訪問并關(guān)注他的博客:https://jl-zhenlaixiaowei.blog.csdn.net/
當(dāng)我還是個(gè)孩子的時(shí)候,我們的鄰居有兩只雙胞胎貓。他們看起來一模一樣——同樣的炭黑色皮毛和同樣刺眼的綠色眼睛。
撇開一些性格怪癖不談,你不能僅僅看它們就區(qū)分它們。但當(dāng)然,它們是兩只不同的貓,兩個(gè)不同的生物,盡管它們看起來完全一樣。
這使我想到了相等和相同之間的含義差異。這種差異對(duì)于理解 Python 的 is 和 == 比較運(yùn)算符的行為方式至關(guān)重要。
== 運(yùn)算符通過檢查是否相等來進(jìn)行比較:如果這些貓是 Python 對(duì)象并且我們將它們與 == 運(yùn)算符進(jìn)行比較,我們會(huì)得到“兩只貓相等”作為答案。
然而,is 運(yùn)算符比較身份(同一性):如果我們將貓與 is 運(yùn)算符進(jìn)行比較,我們會(huì)得到“這是兩只不同的貓”作為答案。
但在我糾結(jié)于這個(gè)麻繩貓的類比之前,讓我們看一下一些真正的 Python 代碼。
首先,我們將創(chuàng)建一個(gè)新的列表對(duì)象并將其命名為 a,然后定義另一個(gè)指向同一個(gè)列表對(duì)象的變量 (b):
In?[2]:?a?=?[1,?2,?3]
In?[3]:?b?=?a
讓我們檢查這兩個(gè)變量。我們可以看到它們指向外觀相同的列表:
In?[4]:?a
Out[4]:?[1,?2,?3]
In?[5]:?b
Out[5]:?[1,?2,?3]
因?yàn)檫@兩個(gè)列表對(duì)象看起來相同,所以當(dāng)我們使用 == 運(yùn)算符比較它們是否相等時(shí),我們將得到預(yù)期的結(jié)果:
In?[6]:?a?==?b
Out[6]:?True
但是,這并不能告訴我們 a 和 b 是否實(shí)際上指向同一個(gè)對(duì)象。
當(dāng)然,我們知道它們是指向同一個(gè)對(duì)象,是因?yàn)槲覀冎爸付怂鼈?,但假設(shè)我們不知道——我們?cè)趺磿?huì)發(fā)現(xiàn)呢?
答案是用 is 運(yùn)算符比較這兩個(gè)變量。這證實(shí)了這兩個(gè)變量實(shí)際上都指向一個(gè)列表對(duì)象:
In?[7]:?a?is?b
Out[7]:?True
讓我們看看當(dāng)我們創(chuàng)建列表對(duì)象的相同副本時(shí)會(huì)發(fā)生什么。我們可以通過在現(xiàn)有列表上調(diào)用 list() 來創(chuàng)建一個(gè)我們將命名為 c 的副本:
In?[8]:?c?=?list(a)
您將再次看到我們剛剛創(chuàng)建的新列表看起來與 a 和 b 指向的列表對(duì)象相同:
In?[9]:?c
Out[9]:?[1,?2,?3]
現(xiàn)在這就是有趣的地方。讓我們使用 == 操作符將我們的列表副本 c 與初始列表 a 進(jìn)行比較。你希望看到什么答案?
In?[10]:?a?==?c
Out[10]:?True
好吧,我希望這是你所期望的。這個(gè)結(jié)果告訴我們的是 c 和 a 具有相同的內(nèi)容。Python 認(rèn)為它們是平等的。但它們實(shí)際上指向的是同一個(gè)對(duì)象嗎?讓我們用 is 運(yùn)算符找出答案:
In?[11]:?a?is?c
Out[11]:?False
砰!這是我們得到不同結(jié)果的所在。Python 告訴我們 c 和 a 指向兩個(gè)不同的對(duì)象,即使它們的內(nèi)容可能相同。
因此,回顧一下,讓我們嘗試將 is 和 == 之間的區(qū)別分解為兩個(gè)簡(jiǎn)短的定義:
如果兩個(gè)變量指向同一個(gè)(相同的)對(duì)象,則 is 表達(dá)式的計(jì)算結(jié)果為 True
如果變量引用的對(duì)象相等(具有相同的內(nèi)容),則 == 表達(dá)式的計(jì)算結(jié)果為 True
附注:本文譯自《Python Tricks:THE BOOK》 作者 :Dan Bade
