Python утверждает для списков поплавков - PullRequest
3 голосов
/ 29 ноября 2011

Использование assert для сравнения списков с плавающей точкой, кажется, работает прямо из коробки - кто-нибудь знает, что происходит за кулисами, например, каково значение EPSILON?

Как программист на Cвсе это заставляет меня чувствовать себя неловко ... я бы подумал, что, возможно, утверждение будет просто сравнивать указатели, но, похоже, оно делает что-то разумное:

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 голосов
/ 29 ноября 2011

Может быть, немного не по теме, но вы не даете много контекста в вашем вопросе.

В различных доступных механизмах модульного тестирования (включая модуль unittest из стандартной библиотеки Python) вы найдете метод TestCase с именем 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 голосов
/ 29 ноября 2011

Сравнение списков с плавающей запятой не утверждается, это оператор == (или operator.eq).list.__eq__ просто откладывает на __eq__ своих предметов.float.__eq__ не выполняет сравнение указателя / идентификатора, а выполняет сравнение значений, но не использует эпсилон любого типа - два числа с плавающей запятой будут сравниваться одинаково, только если они представляют одно и то же значение.

Это почти наверняка не то, что вы хотите, по причинам, обсуждаемым здесь .

5 голосов
/ 29 ноября 2011

Сравнение списков в python с == сравнивает его элементы один за другим.Если вы хотите проверить, является ли это тот же список, используйте is:

>>> a == b
True

>>> a is b
False

>>> e = a
>>> a is e
True

В вашем примере a == b, потому что:

>>> 2.0 == 2.0000000000000001
True

Подробнее о арифметика с плавающей точкой .

2 голосов
/ 03 февраля 2015

Говоря конкретно об утверждениях, можно перейти к простой платформе тестирования с очень удобной функцией:

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
1 голос
/ 29 ноября 2011

Это не имеет ничего общего с утверждениями, не уверен, почему вы их задействуете.Это просто выражение, которое включает сравнение двух списков, тот факт, что результат выражения затем используется в assert, не имеет значения.

И, вероятно, вам следует прочитать What Every Computer ScientistНужно знать об арифметике с плавающей точкой , чтобы узнать больше о точности с плавающей точкой.

...