Python:在nan存在的情况下,sort函数会中断

sorted([2, float('nan'), 1])返回[2, nan, 1]

(至少在Activestate Python 3.1实现上。)

我了解nan是一个奇怪的对象,所以如果它出现在排序结果的随机位置,我不会感到惊讶。 但它也混淆了容器中的非nan数字,这实在是出乎意料。

我问了一个关于max的相关问题,并基于这个我明白了为什么sort是这样的。 但是,这应该被视为一个错误?

文档只是说“返回一个新的排序列表[...]”,而没有指定任何细节。

编辑:我现在同意这不违反IEEE标准。 不过,我认为这是一个来自任何常识观点的错误。 即使微软并不知道他们经常犯错误,但已经认识到这是一个错误,并将其修正为最新版本:http://connect.microsoft.com/VisualStudio/feedback/details/363379/bug-在列表双排序,在列表-其中,包含双南。

无论如何,我结束了@ khachik的回答:

sorted(list_, key = lambda x : float('-inf') if math.isnan(x) else x)

相比于默认的语言,我怀疑它会导致性能下降,但至少它可以工作(禁止我引入的任何错误)。


以前的答案很有用,但可能不清楚问题的根源。

在任何语言中,排序都应用由比较函数或其他方式定义的给定排序在输入值的域上。 例如,当且仅当少于定义一个合适的输入值排序时,小于,也就是operator <,可以在整个过程中使用。

但是,对于浮点值并且小于:“NaN是无序的:它不等于,大于或小于任何东西,包括它本身。” ( 来自GNU C手册的清晰散文,但适用于所有基于IEEE754的现代浮点

所以可能的解决方案是:

  • 首先删除NaN,通过<(或使用其他排序功能)使输入域定义良好,
  • 定义一个自定义的比较函数(aka谓词),确定NaN的排序,例如小于任何数字,或大于任何数字。
  • 任何一种方法都可以用于任何语言。

    实际上,考虑python,如果你不关心最快的性能,或者如果删除NaNs是上下文中期望的行为,我宁愿删除NaN。

    否则,您可以在较早的python版本中通过“cmp”或通过this和functools.cmp_to_key()使用合适的谓词函数。 后者比起先去除NaNs更自然地更尴尬。 定义这个谓词函数时,需要注意避免更糟糕的表现。


    问题是,如果列表包含一个NAN,那么没有正确的顺序,因为如果a1 <= a2 <= a3 <= ... <= an,则会对a1,a2,a3,...,an进行排序。 如果这些值中的任何一个值是NAN,那么排序后的属性会中断,因为对于所有a,a <= NAN和NAN <= a都是false。


    我不确定这个错误,但是解决方法可能如下:

    sorted(
        (2, 1, float('nan')),
        lambda x,y: x is float('nan') and -1 
                    or (y is float('nan') and 1
                    or cmp(x,y)))
    

    这导致:

    ('nan', 1, 2)
    

    或者在排序或其他任何事情之前删除nan

    链接地址: http://www.djcxy.com/p/73351.html

    上一篇: Python: sort function breaks in the presence of nan

    下一篇: Checking if a double (or float) is NaN in C++