8

在 Python 中使用字典时,以下情况是不可能的:

d = {}
d[[1,2,3]] = 4

因为'list' is an unhashable type. 但是,idPython 中的函数会为对象返回一个整数,该整数保证在对象的生命周期内是唯一的。

为什么 Python 不使用id散列字典?有缺点吗?

4

3 回答 3

13

原因就在这里(为什么字典键必须是不可变的)

已经提出的一些不可接受的解决方案:

  • 哈希列表按其地址(对象 ID)。这不起作用,因为如果您构造一个具有相同值的新列表,它将不会被找到;例如:

    mydict = {[1, 2]: '12'}

    print mydict[[1, 2]]

会引发KeyError异常,因为第二行中使用的 id 与[1, 2]第一行中的不同。换句话说,字典键应该用 比较==,而不是用is

于 2013-05-26T05:57:27.887 回答
6

要求 if a == b, then hash(a) == hash(b)。使用id可以打破这一点,因为如果你改变列表,ID 不会改变。然后,您可能有两个内容相同但哈希值不同的列表。

另一种看待它的方式是,是的,您可以这样做,但这意味着您无法使用具有相同内容的另一个列表检索 dict 值。您只能通过使用与键完全相同的列表对象来检索它。

于 2013-05-26T05:58:19.327 回答
1

在 Python 字典中,使用 比较键,使用==列表的相等运算符进行逐项相等检查,因此具有相同元素的两个不同列表比较相等,并且它们必须表现为字典中的相同键。

如果您需要通过身份而不是相等来保留字典或列表集,您可以将列表包装在用户定义的对象中,或者根据上下文,您可以使用字典来存储/检索元素,方法是使用id明确地。

但是请注意,保持id对象的存储并不意味着该对象将保持活动状态,没有办法从id一个对象转到另一个对象,并且id随着时间的推移可能会为已被垃圾收集的对象重用。一个解决方案是使用

my_dict[id(x)] = [x, value]

代替

my_dict[id(x)] = value
于 2013-05-26T06:12:50.503 回答