Человек задал вопрос о том, как получить уникальную функцию списка в 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 равенство с равенством пола
Добавленный Hash PS - это способ сделать из этого класса класс, что класс и две лямбда и возвращают класс, который наследует от первого, переопределяя необходимую функцию равенства.
Это не действительная функция равенства, так как она не транзитивна:
mfloat(0) == mfloat(1) == mfloat(2)
, но mfloat(0) != mfloat(2)
.
Также обратите внимание, что для использования в наборе вы должны переопределить __hash__
чтобы для всех экземпляров a, b вашего класса __hash__
следующее свойство:
a == b ⇒ hash(a) == hash(b)
set обнаруживает, что hash(mfloat(8)) != hash(mfloat(9))
. Так как множество предполагает, что указанное свойство имеет место, он заключает, что mfloat(8) != mfloat(9)
без фактического вызова __eq__
.
from math import floor
class ffloat(float):
def __eq__(self,other):
return floor(self) == floor(other):
def __hash__(self):
return floor(self)
a = map(ffloat,[4.3,8,8.9, 13])
print(set(a))
# output: {8.0, 4.3, 13.0}
__eq__ = lambda x,y: floor(x) = floor(y)
) является переходным. Вы, вероятно, забыли реализовать __hash__ = lambda self: floor(self)
.