Поскольку 1 == 1.0
, это ужасно нарушило бы семантику хеширования (и, следовательно, диктов и множеств), если бы это было так, что hash(1) != hash(1.0)
. В более общем смысле, ВСЕГДА должно быть так, что x == y
подразумевает hash(x) == hash(y)
, для ВСЕХ x
и y
(конечно, нет условий, требующих сохранения обратного значения).
Таким образом, ваш dict d
содержит всего три записи, поскольку вторая, которую вы написали на дисплее dict, переопределяет первую. Если вам нужно, чтобы равенство поддерживалось только между одинаковыми типами (в отличие от чисел в более общем смысле), вам нужна оболочка, такая как:
class W(object):
def __init__(self, x):
self.x = x
self.t = type(x)
def __eq__(self, other):
t = type(other)
if t != type(self):
return False
return self.x == other.x and self.t == other.t
def __hash__(self):
return hash(self.x) ^ hash(self.t)
def __getattr__(self, name):
return getattr(self.x, name)
В зависимости от ваших точных потребностей вы также можете переопределить другие методы (другие методы сравнения, такие как __cmp__
или __le__
, арифметические, __repr__
и т. Д. И т. Д.). В любом случае, это позволит вам создать диктовку, аналогичную той, которая вам требуется, просто используйте в качестве ключей W(1)
вместо голых 1
и W(1.0)
вместо голых 1.0
(вам может не понадобиться переносить числа, хотя это не повредит, если вы решите это сделать, и это может облегчить извлечение из вашего запроса, если все ключи одинаково упакованы).