我有一个dict实例,其中ints,floats,strings作为键,但问题是,当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发布于 2009-08-04 16:47:55
由于1 == 1.0,如果它是hash(1) != hash(1.0)的话,它将可怕地破坏散列的语义(因此字典和集合)。更一般的情况是,对于所有的x和y,x == y必须总是暗示hash(x) == hash(y) (当然没有条件要求反向隐含成立)。
所以您的dict d只有三个条目,因为您在dict display中编写的第二个条目覆盖了第一个条目。如果您需要强制相等仅在相同的类型之间保持(与更一般的数字相反),则需要一个包装器,例如:
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 (您可能不需要包装非数字,尽管如果您选择这样做没有坏处,并且如果所有的键都被相等地包装,则可以更容易地从您的字典中检索)。
发布于 2009-08-04 16:23:37
使用浮点数作为字典键是“不明智的”,不可能保证两个浮点数的值是相同的。
最好的方法是将键值乘以预定的小数位数,并使用该整数作为键值。
编辑:对不起,你似乎不想要一个有实数键的字典,你只是想根据输入的类型格式化输出?
发布于 2009-08-04 17:47:44
如果你真的只需要知道它们的区别,也许可以做一些类似于:
x = '1'
y = 1
hash(type(x) + x) != hash(type(y) + y)https://stackoverflow.com/questions/1228475
复制相似问题