Why does Pylint think this is a redundant comparison? Is this not the fastest way to check for NaN?
Refactor: R0124
Redundant comparison - value_1 != value_1
Redundant comparison - value_2 != value_2
How else am I supposed to check if two values are equal including when they're nan?
NaN = float("NaN")
def compare(value_1, value_2):
match_nan = value_1 != value_1
print(match_nan and
value_2 != value_2 or
value_1 == value_2)
compare(1, 1)
compare(1, NaN)
compare(NaN, 1)
compare(NaN, NaN)
Output:
True
False
False
True
Now, sure math.is_nan is a better solution if you're working with custom classes:
from math import isnan
class NotEQ:
def __eq__(self, other):
return False
not_eq = NotEQ()
print(not_eq != not_eq)
print(isnan(not_eq))
Output:
True
... TypeError: must be real number, not NotEQ
I'm writing a JSON patcher, and I don't think the normal behaviour is very useful when you want to be able to remove them from lists, or raise an error is two values aren't equal (but allowing NaN and NaN)
Use math.isnan(x)
; it's just as fast as x != x
. The answer you cited* that says x != x
is fastest is using a bad test, and I left a comment there to explain:
At this scale (nanoseconds) name and attribute lookup time are significant. If you use only local names, the difference between
x != x
andmath.isnan(x)
disappears; they're both about 35 ns on my system. You can use%timeit
in cell mode to check:
%%timeit x = float('nan')
x != x
36 ns ± 0.51 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%%timeit x = float('nan'); from math import isnan
isnan(x)
35.8 ns ± 0.282 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
* In this comment