使用NaN,可能会得到一个无法正确排序的列表:
--> NaN = float('nan')
--> spam = [1, 2, NaN, 3, NaN, 4, 5, 7, NaN]
--> sorted(spam)
[1, 2, nan, 3, nan, 4, 5, 7, nan]
我正在构造一个Null
对象,其行为与NaN
非常相似,其语义如果返回的对象为Null
,则其实际值未知。 Null
对象也可以与任何其他类型的对象(int
,float
,str
,bool
等进行交互,但任何互动将导致Null
。
从纯粹主义的角度来看,如果未知,那么比较结果也是未知的,因为实际值可能比所比较的值更大,更小或相同。
从实际的角度来看,散落的Nulls列表是背后的痛苦。
所以我非常倾向于实现比较,使得Null对象比其他对象少,所以它们总是排在一起。
当然,我总是可以回避问题并强制用户实现自定义排序键。
任何想法/建议/批评等等?
答案 0 :(得分:5)
NaN
通常被定义为无法与任何东西相比。任何涉及NaN
的计算都应返回NaN
。
事实上:
>>> print float('nan') == float('nan')
False
是的:NaN
与自身并不相同。有这么好的理由,虽然它确实是违反直觉的。主要原因可能是 - 与所有其他数字相比 - 没有唯一方式对它们进行升序排序。应该是第一个,最后一个,到底是什么时候?无限之前或之后?浮点数有几个奇怪的事情。但至少对-infty < -123 < -0 <= +0 < 123 < +infty
毫无疑问。
这不是一个数字,那么它怎么能比一个数字更大,更小或更多?
当然,您可以定义一个自定义比较函数,该函数具有明确定义的NaN
值的排序行为:
def s(x, y):
import math
if math.isnan(x): return 1
return cmp(x, y)
请注意我是如何使用math.isnan
的。此函数具有明确的语义:它首先对所有数字进行排序,然后对任何NaN
值进行排序。
答案 1 :(得分:1)
如果Null
对象实现了比较行为,则其他方法(例如索引)将变得更加复杂。考虑:
target = table.sql('select * where sales < 1000.00')
如果Null
值比较&lt;然后target
所有其他对象可以有没有销售的行(这不是目标)。
所以,我认为实用性和纯度在这一方面都是同一方面:空的比较产生了未知数。如果他们得到Null值,用户将不得不决定如何处理它们。