If you don't compute your floats in the same place or with the exact same equation, then you might have false negatives with this code (because of rounding errors). For example:
>>> 0.1 + 0.2 in [0.6/2, 0.3] # We may want this to be True
False
In this case, we can just have a custom "in" function that will actually make this true (in this case it may be better/faster to use numpy.isclose instead of numpy.allclose):
import numpy as np
def close_to_any(a, floats, **kwargs):
return np.any(np.isclose(a, floats, **kwargs))
There is an important note in the documentation:
Warning
The default atol is not appropriate for comparing numbers that are much smaller than one (see Notes).
[...]
if the expected values are significantly smaller than one, it can result in false positives.
The note adds that atol is not zero contrary to math.isclose's abs_tol. If you need a custom tolerance when using close_to_any, use the kwargs to pass rtol and/or atol down to numpy. In the end, your existing code would translate to this:
if close_to_any(myFloatNumber, myListOfFloats):
print('Found it!')
else:
print('Sorry, no luck.')
Or you could have some options close_to_any(myFloatNumber, myListOfFloats, atol=1e-12), note that 1e-12 is arbitrary and you shouldn't use this value unless you have a good reason to.
Coming back to the rounding error we observed in the first example, this would give:
>>> close_to_any(0.1 + 0.2, [0.6/2, 0.3])
True
myFloatNumberwith a different formula than for the elements ofmyListOfFloats. If you get these number with the exact same code then all errors will be the same and you won't have any problem.3.4 in [3.45, 5] -> False. One option is to cut all floats in the list up to the legnth of the float in question using thedecimalmodule and check then if it is in the listnp.isclose(<your_array>, <your_ref_value>).any(). You can pass tolerances toiscloseif needed.