Python之“==”和“is”區別
導讀 | “==”和“is”都是 Python 中的運算子。對於初學者,他們可能會把“ a==b ”解釋為“ a 等於 b ”,“a is b”也可以解釋為“ a是b ”。這可能就是初學者在 Python 中混淆“ == ”和“ is ”的原因。 |
可能在網上你經常能看到關於這個問題的答案和解析,但是依然有很多剛開始學習Python的人,不瞭解這個問題,也不知道為什麼問這個問題時會暴露自己是“菜鳥”,這個問題就是:
“==”和“is”都是 Python 中的運算子。對於初學者,他們可能會把“ a==b ”解釋為“ a 等於 b ”,“a is b”也可以解釋為“ a是b ”。這可能就是初學者在 Python 中混淆“ == ”和“ is ”的原因。
在開始之前,我想先展示一些使用“==”和“is”的例子。
>>> a = 5 >>> b = 5 >>> a == b True >>> a is b True
很簡單,對吧? a == b 和 a is b 都返回了結果 True。接下來我們看另一個示例:
>>> a = 1000 >>> b = 1000 >>> a == b True >>> a is b False
WTF ?!? 從第一個示例到第二個示例的唯一變化就是 a 和 b 的值從 5 到 1000。但是返回的結果在 “ ==” 和 “ is” 已經不同。我們再看另一個示例:
>>> a = [] >>> b = [] >>> a == b True >>> a is b False
下面是最後一個例子,看完是不是覺得自己的腦子要爆炸?
>>> a = 1000 >>> b = 1000 >>> a == b True >>> a is b False >>> a = b >>> a == b True >>> a is b True
“ ==”的正式運算是相等,而“ is”的運算是標識。 一般使用“ ==”來比較兩個物件的值。 “ a == b”應解釋為“ a的值是否等於b的值”。 在上述所有示例中,a 的值始終等於 b 的值(即使對於空列表示例也是如此)。 因此,“ a == b”始終為真。
在解釋身份之前,我需要先介紹 id 函式。 我們可以使用 id 函式獲得物件的標識。 這個身份在整個時間內對於此物件都是唯一且恆定的。此標識在整個時間內對該物件是唯一且不變的。你可以把它看作是這個物件的地址。如果兩個物件具有相同的標識,則它們的值也必須相同。
>>> id(a) 2047616
運算子“ is ”是比較兩個物件的標識是否相同。“a is b”的意思是“a的身份與b的身份相同”。
如果你知道“ ==”和“ is”的實際含義,我們就可以開始研究上面的幾個示例了。
首先是第一個和第二個示例中的結果不同。 顯示不同結果的原因是Python儲存了一個介於-5到256之間的整數的陣列列表,每個整數具有固定的標識。當我們在此範圍內分配整數變數時,Python會將此變數的標識分配為陣列列表內整數的整數。 結果,對於第一個示例,由於a和b的標識都是從陣列列表中獲得的,因此它們的標識當然是相同的,因此 “a is b” 為True。
>>> a = 5 >>> id(a) 1450375152 >>> b = 5 >>> id(b) 1450375152
但是一旦該變數的值超出該範圍,由於 Python 內部沒有具有該值的物件,因此Python將為此變數建立一個新的標識並將該值分配給該變數。 如前所述,身份對於每個建立都是唯一的,因此,即使兩個變數的值相同,其身份也永遠不會相等。 這就是為什麼“a is b”在第二個例子結果為False。
>>> a = 1000 >>> id(a) 12728608 >>> b = 1000 >>> id(b) 13620208
PS:如果你開啟了兩個控制檯,該值仍在該範圍內,那麼你將獲得相同的標識。但是,如果該值不在該範圍內,則結果就會發生改變。
如果你理解了第一示例和第二示例之間的區別,就很容易理解第三示例的結果。由於 Python 不儲存“空列表”物件,因此 Python 建立了一個新物件並分配了“空列表”值。無論兩個列表為空還是元素相同,結果都是相同的。
>>> a = [1,10,100,1000] >>> b = [1,10,100,1000] >>> a == b True >>> a is b False >>> id(a) 12578024 >>> id(b) 12578056
接下來,我們轉到最後一個示例。第二個和最後一個示例之間的唯一區別是還有一行程式碼 a = b,正是這行程式碼改變了變數 a 的命運。以下結果將告訴你真實原因:
>>> 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 具有相同的標識,因此 a 的值現在與 b 的值相同(即2000)。
最後一個示例告訴我們一個重要訊息,即我們可能會無意中更改物件的值,而不會事先通知,尤其是當物件是列表時。
>>> 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 具有相同的標識,因此它們的值必須相同。 所以,在將新元素新增到 a 之後,b 的值也會受到影響。為避免這種情況,如果要將值從一個物件複製到另一個物件而不引用相同的標識,則所有方法之一是在 copy 模組中使用 deepcopy 。 對於列表,我們還可以透過 b = a [:] 執行。
>>> import copy >>> a = [1,2,3] >>> b= copy.deepcopy(a) >>> id(a) 39785256 >>> id(b) 5237992
使用[:]將元素複製到新變數。
>>> a = [1,2,3] >>> id(a) 39785256 >>> b = a[:] >>> id(b) 23850216 >>> a.append(4) >>> a [1, 2, 3, 4] >>> b [1, 2, 3]
看完以上內容,你是不是已經充分了解了兩者之間的不同?如果面試遇到這種問題,千萬別回答錯啦!
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2712094/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python學習之Pandas和Numpy的區別!Python
- 菜鳥學Python之 _, __ 和 __xx__的區別Python
- Python學習系列之 xrange和range的區別!Python
- 沙師弟學Python之 _, __ 和 __xx__的區別Python
- Python 中 is 和 == 的區別Python
- Python中is和==的區別Python
- Python學習之Django和其他Python框架有什麼區別?PythonDjango框架
- JavaScript之childNodes 和 children 區別JavaScript
- 面試之 get 和 post 區別面試
- count(*) 和count(column)之區別
- Python和C#之間如何選擇?區別介紹PythonC#
- Python學習之Django和Flask框架有什麼區別?PythonDjangoFlask框架
- python ruturn 和 print 的區別Python
- 敏捷和 Scrum 之間的區別敏捷Scrum
- Java之for(;;)和while(true)的區別JavaWhile
- Statement和PreparedStatement之間的區別
- python和r語言的區別PythonR語言
- django classonlymethod 和 python classmethod的區別DjangoPythonSSM
- python is和==的區別是什麼?Python
- Python和C#有哪些區別?PythonC#
- PHP, Python和Java的區別分享PHPPythonJava
- 認清Python下==和is的區別Python
- Python中range和xrange的區別Python
- Python中%r和%s的區別Python
- Python fopen,open,和popen的區別Python
- Python教程:return和yield的區別Python
- Python3中_和__的用途和區別Python
- Python和Go是什麼?它們之間有什麼區別?PythonGo
- Python和access的區別有哪些?Python教程Python
- Python2和Python3的區別Python
- Python引用型別和值型別的區別與使用Python型別
- MySQL之Where和Having的區別MySql
- @Bean和@Component之間的區別?Bean
- MVC,MVP和MVVM之間的區別MVCMVPMVVM
- Java之.class和.getClass()的區別Java
- C++中L和_T()之區別C++
- reboot和init 6之間的區別boot
- Apache Http Server和Tomcat 之區別ApacheHTTPServerTomcat