众所周知,可变类型不能成为字典的关键。
但是如果你使用说C ++,那么常规地图允许你使用矢量和数组作为地图键,因为常规地图被实现为树。
然而,C ++还允许你使用一个数组作为无序映射的关键字,它在精神上更接近python字典,因为只要你为不知道如何的类型提供散列函数它就会散列键。哈希。
所以我想知道只要你提供__hash__
方法,Python是否会让你这样做。
In [1]: b = {}
In [2]: class hlist(list):
...: def __hash__(self):
...: temp = []
...: for item in self:
...: print item
...: temp.append(item)
...: return hash(tuple(temp))
...:
In [3]: a = hlist([1,2,3,4])
In [4]: c = hlist([1,2,3,4])
In [5]: b[a] = "car"
1
2
3
4
In [6]: b[c]
1
2
3
4
Out[6]: 'car'
In [7]: a.append(5)
In [8]: b[c]
1
2
3
4
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-8-013e994efe63> in <module>()
----> 1 b[c]
KeyError: [1, 2, 3, 4]
我在print
中添加了__hash__
以找出正在进行哈希处理的内容以及何时调用该函数。
在抛出KeyError
之前,会打印c
的内容,表示c
只是经过哈希处理。现在不应该只检查这个哈希值是否是其中一个键的哈希值?为什么会出现关键错误?
如果还要逐个哈希所有密钥以确定其中一个密钥是否散列相同的散列值,则查询不应该在下面的代码中工作?
In [11]: b[hlist([1,2,3,4,5])]
1
2
3
4
5
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-11-09593553a69b> in <module>()
----> 1 b[hlist([1,2,3,4,5])]
KeyError: [1, 2, 3, 4, 5]
如果您决定使用具有类似于cpp的半鲁棒散列函数的可变密钥,是否可能?
答案 0 :(得分:0)
如何将记录存储在内存中?(简化版)
hash
,然后键和值都存储在由哈希定义的位置如何从内存中读取dict值?(简化版)
hash
,并根据该哈希计算内存中的位置==
运算符<强>结论强>
要在密码中找到一个密钥(称之为key1
),该密码应包含一个密钥(称之为key2
),其中hash(key1) == hash(key2) and key1 == key2
。
那么为什么可变键是个坏主意?
因为在将密钥写入dict时会计算hash(key)
,并且它在该时间点与key
的值匹配,但如果key
是可变的,并且您在将其变异时它在dict中,dict不会重新计算hash(key)
,因此将无法再找到密钥。