【问题标题】:Comparing lists containing NaNs比较包含 NaN 的列表
【发布时间】:2017-01-03 03:01:37
【问题描述】:

我试图比较两个不同的列表以查看它们是否相等,并打算删除 NaN,结果发现我的列表比较仍然有效,尽管 NaN == NaN -> False

有人可以解释为什么以下评估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 ***

【问题讨论】:

  • 这完全在您链接的第一篇文章中进行了解释-当您在两个列表上测试相等性时,身份在相等性之前测试,nan is nanTrue,因为 nannan 是同一个对象。
  • @Holt 但是在这种情况下如何定义身份,因为没有像 alist = [nan] 这样的声明?这会以某种方式发生在内存中吗?
  • @Holt,在这种情况下,我发现以下内容令人惊讶,因为我认为 float 会创建一个新实例,例如我预计,float(nan) == float(nan)False,但它是 True,而 float(nan) is (float(nan) + 1) --> False
  • @oliversm nan 是内存中的一个对象,因此无论何时使用它,它总是引用同一个对象。当您执行float(nan) 时,什么都不会发生,因为nan 已经是float,而当您执行float('nan')float(nan) + 1 时,会创建一个新对象,因此身份相等不再成立。
  • @oliversm 将nan = np.nan 替换为nan = float('nan') - 您现在有一个名称为nan 的对象,它是float('nan'),根据标准,float('nan') == float('nan')False,但是nan is nan 显然是 True,因为 nannan 是同一个对象!

标签: python list comparison nan


【解决方案1】:

要了解这里发生了什么,只需将nan = np.nan 替换为foo = float('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

【讨论】:

  • 你为什么不期待float(nan) is float(nan)False?在我的控制台中,它评估为True
  • @oliversm 查看第一段代码中的最后一条语句 - 如果type(a) == floatfloat(a) is a 的计算结果为 True
猜你喜欢
  • 2021-06-20
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
  • 2018-01-26
  • 2014-03-16
  • 2022-01-08
相关资源
最近更新 更多