在Python集合中处理float(';nan';)的正确方法是什么?
数字在Python集合中处理float(';nan';)的正确方法是什么?,python,set,nan,Python,Set,Nan,数字float('nan')在Python集合中会导致一些严重的问题。例如,请看以下内容: S = set() S.add(float('nan')) S # {nan} S.add(float('nan')) S.add(float('nan')) S # {nan, nan, nan} len(S) # 3 集合应该每种类型只有一个条目,但每个float('nan')已作为单独的项添加。
float('nan')
在Python集合中会导致一些严重的问题。例如,请看以下内容:
S = set()
S.add(float('nan'))
S # {nan}
S.add(float('nan'))
S.add(float('nan'))
S # {nan, nan, nan}
len(S) # 3
集合应该每种类型只有一个条目,但每个float('nan')
已作为单独的项添加。但当你试图移除它们时,事情变得更加复杂
float('nan') in S # False
S.remove(float('nan'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: nan
S#中的float('nan')为假
S.移除(浮动('nan'))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
关键错误:nan
好的,每个针对float('nan')
的测试结果都是False
,甚至float('nan')==float('nan')
,但对集合的结果是违反直觉的(至少对我来说)。那么,在实践中如何解决以下三个问题:
float('nan')
,如何知道Python集中不同对象的数量浮点('nan')
float('nan')
答案是“以前总是检查,永远不要在集合中添加
float('nan')
”吗?下面的代码可以工作
请注意,它进行字符串比较,因此可能比本机集慢
class NanFriendlyFloatSet(set):
def __getattribute__(self,name):
attr = object.__getattribute__(self, name)
if hasattr(attr, '__call__'):
def new_func(*args, **kwargs):
if attr.__name__ == 'add' and str(args[0]).lower() == 'nan':
return
result = attr(*args, **kwargs)
return result
return new_func
else:
return attr
S1 = NanFriendlyFloatSet()
S1.add(float('nan'))
S1.add(float('nan'))
S1.add(float(34.6))
S1.add(float('nan'))
print(len(S1))
for x in S1:
print(x)
输出
1
34.6
你真的需要存储NaNs吗?它们是如何使用的?如果值为NaN,则可以使用,并插入一个“指示符”值作为替代。避免不惜一切代价将NaN添加到
集合中。要测试nan,请使用import math;print(math.isnan(float('nan'))
这并不能直接解决这个问题,但有助于解释为什么@juanpa.arrivillaga是正确的:@Carcigenicate您通常不知道它。假设您可以解析丢失数据的大型文本文件,或者解析结果会产生float('nan')
。float('nan')
的问题是,您通常根本不知道它们在那里。@gui11aume如果可能,您可能需要先进行检查,然后在找到它们后决定如何处理它们。就像我提到的,你可以用一个自定义的指示符来代替它们,比如NaN\u holder=object()
,然后如果math.isnan(n):s.add(NaN\u holder)else:s.add(n)
,然后在你实际使用数据后决定如何处理NaN\u holder
。谢谢你的建议!如果有什么不同的话,我认为最好是用一个支架来代替它们,而不是忽略浮动('nan')
,正如@Carcigenicate所建议的那样。或者,您甚至可以抛出一个异常,强制用户在出现float('nan')
时执行操作(在此之后,用户可以随心所欲)。