我有一个用户定义的类MyClass
,它具有__hash__
和__eq__
实现,可确保例如:
>>> a = MyClass([100, 99, 98, 97])
>>> b = MyClass([99, 98, 97, 100])
>>> a.__hash__() == b.__hash__()
True
>>> a == b
True
问题:如果我执行以下操作:
>>> x = [a, b]
>>> set(x)
我可以依靠set
保持a
吗?集合__init__
按顺序迭代x
吗?或者我是否需要担心随机使用b
?
谢谢,
麦克
答案 0 :(得分:3)
在这些基于哈希的事情中,它同时使用__hash__
和__eq__
。
如果__hash__
和__eq__
都相同,则获取它在迭代中获得的第一个。当它到达下一个时,它会检查它是否已经拥有它并判定是。
>>> class Same(object):
... def __init__(self, value):
... self.value = value
... def __hash__(self):
... return 42
... def __eq__(self, other):
... return True
... def __repr__(self):
... return 'Same(%r)' % self.value
>>> set([Same(2), Same(1)])
set([Same(2)])
>>> set([Same(1), Same(2)])
set([Same(1)])
使用dict
,它变得更有趣:
>>> {Same(1): 1, Same(2): 2}
{Same(1): 2}
>>> {Same(1): 2, Same(2): 1}
{Same(1): 1}
>>> {Same(2): 1, Same(2): 2}
{Same(2): 2}
>>> {Same(2): 2, Same(2): 1}
{Same(2): 1}
>>> {Same(2): 2, Same(2): 1}
{Same(2): 1}
你应该能够猜出这里发生了什么。它存储第一个项目,然后第二个项目的哈希/相等是相同的;然而,它有不同的价值,所以它存储了。总是会覆盖值,无论它们是否匹配:
>>> {Same(1): Same(2), Same(3): Same(4)}
{Same(1): Same(4)}
我希望有所帮助。
答案 1 :(得分:1)
set
(和dict
)不仅要检查哈希的相等性,还要检查对象本身的相等性。
答案 2 :(得分:1)
我相信set()需要覆盖哈希和 eq 。在这种情况下,你可以使用hash(a)== hash(b),但仍然有一个!= b,假设你以这种方式定义 eq