据我所知,set
在python中通过哈希表来实现O(1)
查找复杂度。虽然它是哈希表,但其中的每个条目set
必须是可散列的(或不可变的)。
所以这种和平的代码引发了异常:
>>> {dict()}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
Because dict
不可散列。但是我们可以创建我们自己的类继承自dict
并实施__hash__
魔法方法。我以这种方式创建了自己的:
>>> class D(dict):
... def __hash__(self):
... return 3
...
我知道它不应该正常工作,但我只是想尝试一下。所以我检查了我现在可以在中使用这种类型set
:
>>> {D()}
{{}}
>>> {D(name='ali')}
{{'name': 'ali'}}
到目前为止一切顺利,但我认为这种实施方式__hash__
魔术方法会搞砸查找set
。因为每一个对象的D
具有相同的哈希值。
>>> d1 = D(n=1)
>>> d2 = D(n=2)
>>> hash(d1), hash(d2)
(3, 3)
>>>
>>> {d1, d2}
{{'n': 2}, {'n': 1}}
但令我惊讶的是:
>>> d3 = D()
>>> d3 in {d1, d2}
False
我预计结果是True
,因为散列d3
is 3
目前我们的集合中存在具有相同哈希值的值。如何set
内部工作?