我有一个 dict
实例,其中 int
、float
、string
作为键,但是问题是当 a
为 int
和 b
为 float
和 float(a) == b
,那么它们的哈希值是相同的,这就是我不想得到的,因为在这种情况下我需要唯一的哈希值才能获得相应的值。
例子:
d = {1:'1', 1.0:'1.0', '1':1, '1.0':1.0}
d[1] == '1.0'
d[1.0] == '1.0'
d['1'] == 1
d['1.0'] == 1.0
我需要的是:
d = {1:'1', 1.0:'1.0', '1':1, '1.0':1.0}
d[1] == '1'
d[1.0] == '1.0'
d['1'] == 1
d['1.0'] == 1.0
最佳答案
自 1 == 1.0
以来,如果 hash(1) != hash(1.0) 会严重破坏散列的语义(因此也破坏了字典和集合)
。更一般地说,对于所有 x
,x == y
必须始终是 hash(x) == hash(y)
和 y
(当然没有条件要求反向蕴涵成立)。
因此您的字典 d
只有三个条目,因为您在字典显示中写入的第二个条目会覆盖第一个条目。如果你需要强制只在相同类型之间保持相等(而不是更普遍的数字),你需要一个包装器,例如:
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
(您可能不需要包装非数字,尽管如果您选择这样做也没有坏处,并且如果所有键都可以简化从字典中的检索同样包裹)。
关于python - 散列函数问题 : hash(1) == hash(1. 0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1228475/