空和排序

时间:2012-01-13 18:51:32

标签: python sorting null python-3.x

使用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对象也可以与任何其他类型的对象(intfloatstrbool等进行交互,但任何互动将导致Null

从纯粹主义的角度来看,如果未知,那么比较结果也是未知的,因为实际值可能比所比较的值更大,更小或相同。

从实际的角度来看,散落的Nulls列表是背后的痛苦。

所以我非常倾向于实现比较,使得Null对象比其他对象少,所以它们总是排在一起。

当然,我总是可以回避问题并强制用户实现自定义排序键。

任何想法/建议/批评等等?

2 个答案:

答案 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值,用户将不得不决定如何处理它们。