2016-08-26 65 views
3

我試圖比較兩個不同的列表以查看它們是否相等,並且要刪除NaN,但僅發現列表比較仍然有效,儘管NaN == NaN -> False比較包含NaN的列表

有人可以解釋爲什麼以下評估TrueFalse,因爲我發現這種行爲出乎意料。謝謝,

我看過這似乎並沒有解決問題的情況如下:

(Python的2.7.3,numpy的-1.9.2)

我已經標記出令人驚訝的評價在末尾

>>> nan = np.nan 
>>> [1,2,3]==[3] 
False 
>>> [1,2,3]==[1,2,3] 
True 
>>> [1,2,nan]==[1,2,nan] 
True *** 
>>> nan == nan 
False 
>>> [nan] == [nan] 
True *** 
>>> [nan, nan] == [nan for i in range(2)] 
True *** 
>>> [nan, nan] == [float(nan) for i in range(2)] 
True *** 
>>> float(nan) is (float(nan) + 1) 
False 
>>> float(nan) is float(nan) 
True *** 
+2

這完全是在你鏈接的第一篇文章解釋 - 當你測試平等的兩個名單,身份在平等之前被測試並且'nan是nan'是'真實的'因爲'nan'和'nan'是同一個對象。 – Holt

+0

@霍爾特,但在這種情況下如何定義身份,因爲沒有像'alist = [nan]'這樣的聲明?莫名其妙地發生在記憶中嗎? –

+0

@Holt,在這種情況下,我發現以下令人驚訝的事情,因爲我認爲'float'會創建一個新實例,我認爲'float(nan)== float(nan)'是'False',但它是'True',而'float(nan)是(float(nan)+ 1) - > False'。 – oliversm

回答

1

要了解這裏發生了什麼,只需更換由foo = float('nan')nan = np.nan,你會得到完全相同的結果,爲什麼呢?

>>> foo = float('nan') 
>>> foo is foo # This is obviously True! 
True 
>>> foo == foo # This is False per the standard (nan != nan). 
False 
>>> bar = float('nan') # foo and bar are two different objects. 
>>> foo is bar 
False 
>>> foo is float(foo) # "Tricky", but float(x) is x if type(x) == float. 
True 

現在認爲numpy.nan僅僅是持有float('nan')一個變量名。

現在爲什麼[nan] == [nan]僅僅是因爲價值面前人人平等項目之間list比較第一次測試的身份平等,認爲它是:

def equals(l1, l2): 
    for u, v in zip(l1, l2): 
     if u is not v and u != v: 
      return False 
    return True 
+0

爲什麼你不期望'float(nan)是float(nan)'是'False'?在我的控制檯中,它評估爲「真」。 – oliversm

+1

@oliversm查看第一個代碼塊中的最後一個語句 - 如果type(a)== float',float(a)是''評估爲'True'。 – Holt