我定义的一个类在set()
中用于过滤掉相等的对象。但它没有像我期望的那样起作用,所以我显然明白了一些错误。
class Foo(object):
def __hash__(self):
return 7
x = set()
x.add(Foo())
assert len(x) == 1
x.add(Foo())
assert len(x) == 1 # AssertionError
我希望该集合只包含一个元素,但它有两个元素。那是为什么?
答案 0 :(得分:6)
知道哈希冲突发生在集合(哈希映射)中,没有哈希算法足以为每个项目提供唯一的哈希值,否则需要很长时间才能计算出来。当发生碰撞时,python会回退到使用__eq__
检查值的相等性,以确保它们不相同。
class Foo(object):
def __hash__(self):
return 7
def __eq__(self, other):
return True
>>> x = set()
>>> x.add(Foo())
>>> assert len(x) == 1
>>> x.add(Foo())
>>> assert len(x) == 1
>>>
这就是为什么你看到可怕的运行时超过here的原因,但请注意,即使它们有O(N)最坏情况(一切都是哈希冲突),你可以期待O(1)摊销的成员资格检查。 )。由于Python的智能实现,最糟糕的情况非常不太可能发生。