bph
bph

Reputation: 11258

python assert for lists of floats

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

Answers (5)

bobleponge
bobleponge

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

gurney alex
gurney alex

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

eumiro
eumiro

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

unwind
unwind

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

babbageclunk
babbageclunk

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

Related Questions