如何在Python中覆盖列表中浮动的比较?

时间:2015-07-15 16:22:56

标签: python override comparison-operators

我试图检查两个正常的向量是否相等。我的法线向量表示为三元素列表,每个空间坐标(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。那么有一种方法可以覆盖equals运算符来接受彼此在0.0001内的答案,这些答案与其他数据结构中的比较(如我的情况下的列表)兼容吗?我有一种感觉,我必须编写自己的__eq__方法,但我不太确定如何做到这一点。

另外,如果这不是最好的行动方案,那么他们是否可以更好地比较给定公差范围内的两个浮动列表?

2 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

您无法更改内置的List属性,但您可以通过扩展到自己的list子类来覆盖它们。

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,这在检查相等性方面有所不同。

希望这可以解决你的问题..