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

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

我正在尝试检查两个法向量是否相等。我的法向量表示为一个三元素列表,一个元素对应每个空间坐标(X、Y 和 Z)。所有坐标都四舍五入到小数点后 4 位。我想检查两个表面是否具有相同的法线,所以我有如下内容:

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

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

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

请注意,z 坐标偏移了 0.0001。那么有没有一种方法可以覆盖等于运算符以接受彼此在 0.0001 范围内的答案,这与其他数据结构中的比较兼容(如我的情况下的列表)?我有一种感觉,我必须编写自己的 __eq__ 方法,但我不太确定该怎么做。

另外,如果这不是最好的做法,他们是否是在给定公差范围内比较两个浮动列表的更好方法?

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

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

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

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

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 值。

正如我所说,l == l1 在 python 中被转换为 l.__eq__(l1),因此您必须添加 deviation 属性 以列出位于左边到 ==

如果你运行上面的脚本..

# Output ---------------
True

这是因为我们已经定义了 l.deviation == 0.0001,这在检查相等性方面有所不同。

希望这能解决您的问题..