如何在python中覆盖列表中浮点数的比较?

How to override comparison for floats in a list in Python?

我试图检查两个法向量是否相等。我的法向量表示为一个三元素列表,每个空间坐标(x、y和z)对应一个元素。所有坐标四舍五入到小数点后4位。我想检查两个表面是否具有相同的法向,因此我有如下内容:

1
2
if (surface1.normal in [surface2.normal, self.NegatedNormal(surface2.normal)]):
    # do stuff here

问题是我的法线看起来像这样:

1
2
surface1.normal: [0.9947, 0.0155, 0.1015]
surface2.normal: [0.9947, 0.0155, 0.1014]

请注意,Z坐标关闭0.0001。那么,是否有一种方法可以重写equals运算符,以接受相互之间0.0001以内的答案,这与其他数据结构(如我的示例中的列表)中的比较相兼容?我有一种感觉,我必须写自己的eq方法,但我不太确定该怎么做。

此外,如果这不是最佳的操作过程,那么它们是比较给定公差内两个浮动列表的更好方法吗?


您可以编写一个自定义函数来执行此操作。例如:

1
2
def comp_floats(x, y, delta):
    return abs(x - y) < delta

显然,您可以在函数本身中进行任何类型的错误更正,但这只是一个示例。


不能更改内置列表属性,但可以通过扩展到自己的列表子类来覆盖这些属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class CustomList(list):
    deviation = None

    def deviation_check(self, val1, val2):
       if self.deviation:
           return min(val1, val2) + self.deviation >= max(val1, val2)
       return val1 == val2

    def __eq__(self, other):
        is_equal = (self.deviation_check(self[0], other[0]) and
                   self.deviation_check(self[1], other[1]) and
                   self.deviation_check(self[2], other[2]))

        return is_equal

l = CustomList()
l.deviation = 0.0001 # Note: Added deviation as a property
l.extend([0.9947, 0.0155, 0.1015])

l1 = CustomList()
l1.extend([0.9947, 0.0155, 0.1014])

print l == l1

现在我们有两个customlist对象l和l1,当您试图检查列表l == l1之间的相等性时,python会用这种方式检查它的相等性。l.__eq__(l1),所以这就是为什么我们超越了__eq__的魔法方法,让它按照我们喜欢的方式工作。

如果不添加l.deviation,它将检查是否相等。另外,你必须清楚你要在哪边加上deviation的值。

如我所说,在python中l == l1被转换成l.__eq__(l1),所以您需要添加deviation属性来列出==左侧的对象。

如果运行上面的脚本..

1
2
# Output ---------------
True

这是因为我们已经定义了l.deviation == 0.0001,这在检查相等性方面产生了差异。

希望这能解决你的问题。