Python 中对浮点数列表的 assert 语句

4 投票
5 回答
8835 浏览
提问于 2025-04-17 07:18

使用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)——两个浮点数只有在它们的值完全相同的时候才会被认为是相等的。

这几乎肯定不是你想要的,具体原因可以在这里找到。

撰写回答