在 如何哈希列表? 有人告诉我应该先转换为元组,例如 [1,2,3,4,5]
到 (1,2,3,4,5)
。
所以第一个不能散列,但第二个可以。为什么* ?
*我并不是真的在寻找详细的技术解释,而是在寻找直觉
原文由 gsamaras 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 如何哈希列表? 有人告诉我应该先转换为元组,例如 [1,2,3,4,5]
到 (1,2,3,4,5)
。
所以第一个不能散列,但第二个可以。为什么* ?
*我并不是真的在寻找详细的技术解释,而是在寻找直觉
原文由 gsamaras 发布,翻译遵循 CC BY-SA 4.0 许可协议
你完全可以做到这一点,但我打赌你不会喜欢这些效果。
from functools import reduce
from operator import xor
class List(list):
def __hash__(self):
return reduce(xor, self)
现在让我们看看会发生什么:
>>> l = List([23,42,99])
>>> hash(l)
94
>>> d = {l: "Hello"}
>>> d[l]
'Hello'
>>> l.append(7)
>>> d
{[23, 42, 99, 7]: 'Hello'}
>>> l
[23, 42, 99, 7]
>>> d[l]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: [23, 42, 99, 7]
编辑: 所以我想了更多。如果您返回列表的 id 作为它的哈希值,您可以使上面的示例工作:
class List(list):
def __hash__(self):
return id(self)
在这种情况下, d[l]
d[[23,42,99,7]]
d[List([23,42,99,7])]
提供 'Hello'
,但都不 [Ll]ist
。
原文由 L3viathan 发布,翻译遵循 CC BY-SA 3.0 许可协议
2 回答5k 阅读✓ 已解决
2 回答1k 阅读✓ 已解决
4 回答934 阅读✓ 已解决
3 回答1.1k 阅读✓ 已解决
3 回答1.1k 阅读✓ 已解决
1 回答1.7k 阅读✓ 已解决
1 回答1.2k 阅读✓ 已解决
主要是因为元组是不可变的。假设以下工作:
现在,当您执行
l.append(4)
时会发生什么?您已经修改了字典中的键!远道而来!如果您熟悉散列算法的工作原理,这应该会吓到您。另一方面,元组是绝对不可变的。t += (1,)
可能看起来它正在修改元组,但实际上它不是:它只是创建一个 新 的元组,让你的字典键保持不变。