在 Python 中使用字典时,以下情况是不可能的:
d = {}
d[[1,2,3]] = 4
因为'list' is an unhashable type
. 但是,id
Python 中的函数会为对象返回一个整数,该整数保证在对象的生命周期内是唯一的。
为什么 Python 不使用id
散列字典?有缺点吗?
在 Python 中使用字典时,以下情况是不可能的:
d = {}
d[[1,2,3]] = 4
因为'list' is an unhashable type
. 但是,id
Python 中的函数会为对象返回一个整数,该整数保证在对象的生命周期内是唯一的。
为什么 Python 不使用id
散列字典?有缺点吗?
原因就在这里(为什么字典键必须是不可变的)
已经提出的一些不可接受的解决方案:
哈希列表按其地址(对象 ID)。这不起作用,因为如果您构造一个具有相同值的新列表,它将不会被找到;例如:
mydict = {[1, 2]: '12'}
print mydict[[1, 2]]
会引发
KeyError
异常,因为第二行中使用的 id 与[1, 2]
第一行中的不同。换句话说,字典键应该用 比较==
,而不是用is
。
要求 if a == b
, then hash(a) == hash(b)
。使用id
可以打破这一点,因为如果你改变列表,ID 不会改变。然后,您可能有两个内容相同但哈希值不同的列表。
另一种看待它的方式是,是的,您可以这样做,但这意味着您无法使用具有相同内容的另一个列表检索 dict 值。您只能通过使用与键完全相同的列表对象来检索它。
在 Python 字典中,使用 比较键,使用==
列表的相等运算符进行逐项相等检查,因此具有相同元素的两个不同列表比较相等,并且它们必须表现为字典中的相同键。
如果您需要通过身份而不是相等来保留字典或列表集,您可以将列表包装在用户定义的对象中,或者根据上下文,您可以使用字典来存储/检索元素,方法是使用id
明确地。
但是请注意,保持id
对象的存储并不意味着该对象将保持活动状态,没有办法从id
一个对象转到另一个对象,并且id
随着时间的推移可能会为已被垃圾收集的对象重用。一个解决方案是使用
my_dict[id(x)] = [x, value]
代替
my_dict[id(x)] = value