如何覆盖 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
,这在检查相等性方面有所不同。
希望这能解决您的问题..
我正在尝试检查两个法向量是否相等。我的法向量表示为一个三元素列表,一个元素对应每个空间坐标(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
,这在检查相等性方面有所不同。
希望这能解决您的问题..