4 个回答

2

如果你只是想知道它们之间的区别,或许可以试试下面这种简单的方法:

x = '1'
y = 1

hash(type(x) + x) != hash(type(y) + y)
6

把浮点数作为字典的键是不太明智的,因为我们无法保证两个浮点数会被认为是相同的值。

最好的办法是把这些键乘以一个固定的小数位数,然后用这个整数作为键。

补充说明:抱歉,看起来你并不是想要一个带有真实数字键的字典,你只是想根据输入的类型来格式化输出?

7

因为 1 == 1.0,如果 hash(1)hash(1.0) 不相等的话,会严重影响哈希的意义(因此也会影响字典和集合)。更一般来说,对于所有的 xy,如果 x == y 成立,那么 hash(x) == hash(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(你可能不需要对非数字进行包装,虽然如果你选择这样做也没问题,而且如果所有键都被包装,可能会更方便从字典中取值)。

撰写回答