我有一个dict
的实例,int
s,float
s,string
s作为键,但问题是当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}}
答案 0 :(得分:7)
从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
(你可能不需要包装非数字,虽然如果你选择这样做没有任何伤害,如果所有的键都被包裹起来,它可以简化你的dict中的检索。)
答案 1 :(得分:6)
使用float作为字典键是“不明智的”,不可能保证两个浮点值将评估为相同的值。
最好的方法是将密钥乘以预定的小数位数,并使用该整数作为密钥。
编辑:很抱歉,你似乎不想要一个带有实数键的字典,你只想根据输入的类型格式化输出?
答案 2 :(得分:2)
如果你真的只是需要了解其中的差异,也许可以做一些像黑客这样的事情:
x = '1'
y = 1
hash(type(x) + x) != hash(type(y) + y)
答案 3 :(得分:1)
这并不能解决您的问题,而是来自Python 2.6's number documentation:
实现者应该小心使相等的数字相等并将它们哈希到相同的值。
你可以通过制作浮动1.00001,或类似的东西吗?