Reputation: 11258
using assert to compare lists of floats seems to work straight out of the box as it were - does anyone know what goes on behind the scenes, e.g. what is the value of EPSILON?
As a C programmer this is all making me feel uneasy... I would have thought maybe the assert would just be comparing pointers but it does seem to be doing something sensible:
a = [1.0,2.0]
b = [1.0,2.0]
c = [1.0,2.01]
d = [1.0, 2.0000000000000001]
assert a==b # ok
assert a==c # no go
assert a==d # ok
Upvotes: 4
Views: 9455
Reputation: 161
Talking about asserts specifically, an option is to go for numpy testing framework with the highly convenient function:
import numpy as np
np.testing.assert_almost_equal([1.0001, 2.], [1., 2.], decimal=3)
# OK
np.testing.assert_almost_equal([1.0001, 2.], [1., 2.], decimal=6)
# NOT OK
Upvotes: 3
Reputation: 13645
Maybe slightly off-topic, but you don't give much context in your question.
In the various unit testing machineries available (including the unittest
module from the Python standard library), you will find a TestCase
method called assertAlmostEqual(v1, v2, tol)
which you can use to write tests about floating point results of function / method calls. If your function / method returns a list of floats, then it is quite easy to define a new TestCase
method:
def assertListAlmostEqual(self, list1, list2, tol):
self.assertEqual(len(list1), len(list2))
for a, b in zip(list1, list2):
self.assertAlmostEqual(a, b, tol)
(work required to provide nice error messages in test reports is left as an exercice to the reader)
Upvotes: 7
Reputation: 212915
Comparing lists in python with ==
compares its elements one after another. If you want to test whether it is the same list, use is
:
>>> a == b
True
>>> a is b
False
>>> e = a
>>> a is e
True
In your example, a == b
because:
>>> 2.0 == 2.0000000000000001
True
Read more about floating point arithmetics.
Upvotes: 5
Reputation: 399871
This has nothing to do with asserts, not sure why you involve them. It's just an expression that includes a comparison of two lists, the fact that the result of the expression is then used in an assert doesn't matter.
And, you should probably read What Every Computer Scientist Should Know About Floating-Point Arithmetic to learn more about precision with floating-point.
Upvotes: 1
Reputation: 8731
It's not assert that is comparing the lists of floats, it's the ==
operator (or operator.eq
). list.__eq__
is just deferring to the __eq__
of its items. float.__eq__
isn't doing a pointer/identity comparison, it's doing a value comparison, but it's not using any kind of epsilon - two floats will only compare equal if they represent exactly the same value.
This is almost certainly not what you want, for the reasons discussed here.
Upvotes: 5