我做错了什么(在 python 中通过重载实现替代相等)
有人在 SO 上提出了一个问题,关于如何使用替代的相等函数在 python 中获取列表唯一函数。
我认为这可以通过从元素类继承并重载相等函数来完成,
import functools
@functools.total_ordering
class ffloat(float):
def __eq__(self,other):
if floor(self) == floor(other):
return True
else:
return False
def __le__(self,other):
if self == other:
return True
else:
return float(self) <= float(other)
def __hash__(self):
return floor(self)
a = map(ffloat,[4.3,8,8.9, 13])
In [41]: a[1] == a[2]
Out[41]: True
但是
In [42]: set(a)
Out[42]: set([4.3, 8.0, 8.9, 13.0])
编辑:替换了abs < 1.5 平等与下限平等
添加了哈希值 PS 有一种方法可以用一个类和两个 lambda 来创建一个类工厂,并返回一个继承自第一个类的类,覆盖所需的相等函数。
A person asked a question on SO about how to get a list unique function in python with an alternative equality function.
I was thinking it could be done by inheriting from the element class and overloading the equality function
import functools
@functools.total_ordering
class ffloat(float):
def __eq__(self,other):
if floor(self) == floor(other):
return True
else:
return False
def __le__(self,other):
if self == other:
return True
else:
return float(self) <= float(other)
def __hash__(self):
return floor(self)
a = map(ffloat,[4.3,8,8.9, 13])
In [41]: a[1] == a[2]
Out[41]: True
but
In [42]: set(a)
Out[42]: set([4.3, 8.0, 8.9, 13.0])
Edit: replaced abs < 1.5 equality with floor equality
Added Hash
P.S. is there a way to make a class factory out of this that a class and two lambda and returns a class that inherits from the first one overriding the needed equality function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这不是一个有效的相等函数,因为它不是传递:
mfloat(0) = = mfloat(1) == mfloat(2)
,但是mfloat(0) != mfloat(2)
。另请注意,为了在集合中使用,您必须覆盖
__hash__
以便以下属性适用于类的所有实例 a、b:set 发现
hash(mfloat(8)) != hash(mfloat(9))
。由于 set 假定上述属性成立,因此它会得出mfloat(8) != mfloat(9)
的结论,而无需实际调用__eq__
。In summary, this works:
This is not a valid equality function, since it's not transitive:
mfloat(0) == mfloat(1) == mfloat(2)
, butmfloat(0) != mfloat(2)
.Also note that in order to be used in a set, you must override
__hash__
so that the following property holds for all instances a, b of your class:set finds out that
hash(mfloat(8)) != hash(mfloat(9))
. Since set assumes the above property holds, it concludes thatmfloat(8) != mfloat(9)
without actually calling__eq__
.In summary, this works: