2011-04-25 163 views
7

我不清楚語法!=is not之間的區別。他們似乎做同樣的事情:Python:!=和「不是」之間的區別

>>> s = 'a' 
>>> s != 'a' 
False 
>>> s is not 'a' 
False 

但是,當我在一個列表理解使用is not,它會產生不同的結果,如果我用!=

>>> s = "hello" 
>>> [c for c in s if c is not 'o'] 
['h', 'e', 'l', 'l', 'o'] 
>>> [c for c in s if c != 'o'] 
['h', 'e', 'l', 'l'] 

爲什麼o獲得列入第一個列表,而不是第二個列表?

+3

當您查看這兩個運算符的Python語言參考時,您看到了什麼?這看起來很清楚:http://docs.python.org/reference/expressions.html#notin。什麼讓你感到困惑? – 2011-04-25 19:40:29

+0

@ FChannel72我認爲在表達式「c不是'o'''中**的存在會引起對」id(c)不是'o'''的評估。由於一個數字(地址id(c))不是一個字符串,所以測試結果爲True,所以** c **保存在構建的列表中。 – eyquem 2011-04-25 20:04:34

+0

@ FChannel72問題是我驗證了你的結果,並且我爲這兩個表達式獲得了''['h','e','l','l']'!我想知道爲什麼,如果''is''的存在引發比較id(c),它不會引起與id('o')的比較。事實上,看起來''c不是'o'''被評估爲''id(c)!= id('o')''...在我的Python 2.7 – eyquem 2011-04-25 20:13:24

回答

19

is試驗對象的身份,但==試驗對象的值相等:

In [1]: a = 3424 
In [2]: b = 3424 

In [3]: a is b 
Out[3]: False 

In [4]: a == b 
Out[4]: True 
+2

原因對於op的例子中的字符串不起作用是python方法的工件將字符串分配給變量。由於字符串是不可變的,因此在全局名稱空間中,包含相同字符串的兩個變量將引用同一個對象。 – Wilduck 2011-04-25 19:41:50

+0

你使用什麼樣的Python?在Python 2.7中,對於「a是b」的指令,我獲得了True! – eyquem 2011-04-25 20:00:06

+0

這是使用Python 2.6.4。該實現可以選擇緩存某些對象。在我的系統中,「a」通過了「is」測試,但「蘋果醬」沒有通過。 – tkerwin 2011-04-25 20:54:42

5

is not比較引用。 ==比較值

+0

爲什麼設置'a = 123'後'a == 123'返回true? – ajwood 2011-04-25 19:31:15

+1

@ajwood:因爲它們具有相同的價值。 '=='比較值。 – Wilduck 2011-04-25 19:40:41

+1

更好的問題是爲什麼「a是123」在大多數實現中返回True。 (請參閱http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly-with-integers) – geoffspear 2011-04-25 19:44:45

1

根據您的困惑程度,這可能會有所幫助。

這些語句是相同的:

[c for c in s if c != 'o'] 
[c for c in s if not c == 'o'] 
0

我剛從參考報價,操作數 is測試是否是一個相同的,很可能指的是同一個對象。如!=測試該值。

s = [1,2,3] 
while s is not []: 
    s.pop(0); 

這是一個無限循環,因爲對象s永遠不會等於[]的對象引用,它指的是一個完全不同的對象。如果用s != []代替條件將會使循環明確,因爲在這裏我們正在比較值,當s中的所有值都彈出時剩下的就是一個空列表。

-1

我想補充一點,他們肯定不會做同樣的事情。 我會用!=。 舉例來說,如果你有一個unicode字符串....

a = u'hello' 
'hello' is not a 
True 
'hello' != a 
False 

有了!=,Python的基本而有沒有,如果它匹配執行從STR()轉換爲Unicode的隱式轉換(),並比較,它是完全一樣的實例。