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
的现代浮点 )
所以可能的解决方案是:
任何一种方法都可以用于任何语言。
实际上,考虑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
。