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.
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: