Python 中对浮点数列表的 assert 语句
使用assert来比较浮点数列表似乎可以直接使用,大家知道背后发生了什么吗?比如,EPSILON的值是什么?
作为一个C语言程序员,这让我感到有点不安……我本以为assert只是比较指针,但它似乎在做一些合理的事情:
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
5 个回答
5
在Python中,用 ==
来比较列表时,是一个一个元素地进行比较。如果你想检查两个列表是不是同一个列表,应该使用 is
:
>>> a == b
True
>>> a is b
False
>>> e = a
>>> a is e
True
在你的例子中, a == b
是因为:
>>> 2.0 == 2.0000000000000001
True
想了解更多,可以阅读关于 浮点数运算 的内容。
7
这可能有点偏题,但你在问题中没有提供太多背景信息。
在各种单元测试工具中(包括Python标准库里的unittest
模块),你会发现一个叫assertAlmostEqual(v1, v2, tol)
的方法。这个方法可以用来测试函数或方法返回的浮点数结果。如果你的函数或方法返回的是一个浮点数列表,那么定义一个新的TestCase
方法就非常简单了:
def assertListAlmostEqual(self, list1, list2, tol):
self.assertEqual(len(list1), len(list2))
for a, b in zip(list1, list2):
self.assertAlmostEqual(a, b, tol)
(为了在测试报告中提供友好的错误信息,这部分工作留给读者自己去做)
5
这里不是在用assert来比较浮点数列表,而是用的==
运算符(或者说operator.eq
)。list.__eq__
其实只是把比较工作交给了它里面每个元素的__eq__
。而float.__eq__
并不是在比较指针或身份,它是在比较数值,但它没有使用任何容差(epsilon)——两个浮点数只有在它们的值完全相同的时候才会被认为是相等的。
这几乎肯定不是你想要的,具体原因可以在这里找到。