我有两种算法,理论上应该执行相同的任务,我想检查它们是否确实如此。
它们各自返回一个包含混合数据类型(数字、列表、字符串)的大列表。我想检查这两个列表是否相同。
简单的方法是
assert list1 == list2
。但是,由于数值错误,有时list1
中的一个元素是5
,而list2
中对应的元素是5.000003
。这仍然会触发断言False
,但我想忽略这么小的错误。
如何实现这个“检查数字错误的身份”?
我认为列表包含混合数据类型(不仅仅是数字)这一事实使问题复杂化。
基本公式是这样的:
len(list1) == len(list2) and all(is_close(a, b) for a, b in zip(list1, list2))
具有一些功能
is_close
,您可以使用它来比较两个元素,可能类似于:
def is_close(a, b):
return a == b or (
isinstance(a, (float, int)) and isinstance(b, (float, int))
and abs(a - b) < 0.000005
)
对于不同数据类型的一般
a == b
规则可能有其他例外情况。它甚至可以递归定义来处理嵌套数据:
def is_close(a, b):
return a == b or (
isinstance(a, (float, int)) and isinstance(b, (float, int))
and abs(a - b) < 0.000005
) or (
isinstance(a, list) and isinstance(b, list)
and len(a) == len(b)
and all(is_close(*z) for z in zip(a, b))
) or (
isinstance(a, dict) and isinstance(b, dict)
and a.keys() == b.keys()
and all(is_close(a[k], b[k]) for k in a)
) # etc?
简而言之,您可以创建一个自定义列表类并重载
==
运算符。
class CustomList(list):
def __eq__(self, other):
if CUSTOM LOGIC HERE:
return true
else:
return false
然后您可以像使用内置 Python 列表一样使用 CustomList。
my_custom_list = CustomList([1, 2, 3])
因为你只重载了
__eq__
方法,它的行为就像一个普通的列表,除了它会有用于比较列表的自定义逻辑。