首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >散列函数的问题:散列(1) ==散列(1.0)

散列函数的问题:散列(1) ==散列(1.0)
EN

Stack Overflow用户
提问于 2009-08-04 16:17:40
回答 4查看 714关注 0票数 1

我有一个dict实例,其中ints,floats,strings作为键,但问题是,当a作为intb作为float,以及float(a) == b时,它们的散列值是相同的,这是我不想得到的,因为在这种情况下,我需要唯一的散列值才能获得相应的值。

示例:

代码语言:javascript
复制
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

我需要的是:

代码语言:javascript
复制
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
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-08-04 16:47:55

由于1 == 1.0,如果它是hash(1) != hash(1.0)的话,它将可怕地破坏散列的语义(因此字典和集合)。更一般的情况是,对于所有的xyx == y必须总是暗示hash(x) == hash(y) (当然没有条件要求反向隐含成立)。

所以您的dict d只有三个条目,因为您在dict display中编写的第二个条目覆盖了第一个条目。如果您需要强制相等仅在相同的类型之间保持(与更一般的数字相反),则需要一个包装器,例如:

代码语言:javascript
复制
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)代替空的1W(1.0)代替空的1.0 (您可能不需要包装非数字,尽管如果您选择这样做没有坏处,并且如果所有的键都被相等地包装,则可以更容易地从您的字典中检索)。

票数 7
EN

Stack Overflow用户

发布于 2009-08-04 16:23:37

使用浮点数作为字典键是“不明智的”,不可能保证两个浮点数的值是相同的。

最好的方法是将键值乘以预定的小数位数,并使用该整数作为键值。

编辑:对不起,你似乎不想要一个有实数键的字典,你只是想根据输入的类型格式化输出?

票数 6
EN

Stack Overflow用户

发布于 2009-08-04 17:47:44

如果你真的只需要知道它们的区别,也许可以做一些类似于:

代码语言:javascript
复制
x = '1'
y = 1

hash(type(x) + x) != hash(type(y) + y)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1228475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档