[英]What does set() in Python use to test equality between objects?
I have written some code in Python which has a class called product and overrided the magic functions __eq__
and __hash__
.我用 Python 编写了一些代码,其中有一个名为 product 的类并覆盖了魔术函数
__eq__
和__hash__
。 Now I need to make a set which should remove duplicates from the list based on the ID
of the product.现在我需要创建一个集合,它应该根据产品的
ID
从列表中删除重复项。 As you can see the output of this code the hashes of two objects are the same, yet when i make a set of those two objects the length is 2 not one.正如您所看到的这段代码的输出,两个对象的哈希值是相同的,但是当我创建一组这两个对象时,长度是 2 而不是 1。
But, when i change the __eq__
method of the code to this但是,当我将代码的
__eq__
方法更改为此
def __eq__(self, b) -> bool:
if self.id == b.id:
return True
return False
and use it with the same hash function it works and the length of the set is 1. So i am confused whether the set data-structure uses the __eq__
method to test for equality or the __hash__
method.并将它与它工作的相同散列函数一起使用,并且集合的长度为 1。所以我很困惑集合数据结构是使用
__eq__
方法来测试相等性还是使用__hash__
方法。
Equality tests can be expensive, so the set starts by comparing hashes.相等测试可能很昂贵,因此该集合从比较散列开始。 If the hashes are not equal, then the check ends.
如果散列不相等,则检查结束。 If the hashes are equal, the set then tests for equality.
如果散列相等,则集合测试相等。 If it only used
__eq__
, it might have to do a lot of unnecessary work, but if it only used __hash__
, there would be no way to resolve a hash collision.如果它只使用
__eq__
,它可能需要做很多不必要的工作,但如果它只使用__hash__
,将无法解决哈希冲突。
Here's a simple example of using equality to resolve a hash collision.这是一个使用相等来解决哈希冲突的简单示例。 All integers are their own hashes, except for
-1
:所有整数都是它们自己的哈希值,除了
-1
:
>>> hash(-1)
-2
>>> hash(-2)
-2
>>> s = set()
>>> s.add(-1)
>>> -2 in s
False
Here's an example of the set skipping an equality check because the hashes aren't equal.这是由于散列不相等而跳过相等检查的集合的示例。 Let's subclass an
int
so it return a new hash every second:让我们继承一个
int
类,让它每秒返回一个新的散列:
>>> class TimedInt(int):
... def __hash__(self):
... return int(time.time())
...
>>> a = TimedInt(5)
>>> a == 5
True
>>> a == a
True
>>> s = set()
>>> s.add(a) # Now wait a few seconds...
>>> a in s
False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.