Aid*_*adi 11 python hash set python-datamodel python-3.x
我正在使用类set()
和__hash__
方法python
来防止在set中添加相同的哈希对象.根据python数据模型文档,set()
将相同的哈希对象视为同一个对象,只需添加一次即可.
但它的行为如下:
class MyClass(object):
def __hash__(self):
return 0
result = set()
result.add(MyClass())
result.add(MyClass())
print(len(result)) # len = 2
Run Code Online (Sandbox Code Playgroud)
在字符串值的情况下,它可以正常工作.
result.add('aida')
result.add('aida')
print(len(result)) # len = 1
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么相同的哈希对象在集合中不相同?
Ant*_*ala 17
你的阅读不正确.该__eq__
方法用于相等性检查.该文件只是指出该__hash__
值也必须是相同的两个对象a
,并b
为它a == b
(即 a.__eq__(b)
)是真实的.
这是一个常见的逻辑错误:a == b
真实意味着这hash(a) == hash(b)
也是正确的.然而,暗示并不一定意味着等同,除了先验之外,hash(a) == hash(b)
意味着a == b
.
为了使所有MyClass
比较实例彼此相等,您需要__eq__
为它们提供一种方法; 否则Python会比较他们的身份.这可能会:
class MyClass(object):
def __hash__(self):
return 0
def __eq__(self, other):
# another object is equal to self, iff
# it is an instance of MyClass
return isinstance(other, MyClass)
Run Code Online (Sandbox Code Playgroud)
现在:
>>> result = set()
>>> result.add(MyClass())
>>> result.add(MyClass())
1
Run Code Online (Sandbox Code Playgroud)
实际上,您将基于__hash__
用于__eq__
比较的对象的属性,例如:
class Person
def __init__(self, name, ssn):
self.name = name
self.ssn = ssn
def __eq__(self, other):
return isinstance(other, Person) and self.ssn == other.ssn
def __hash__(self):
# use the hashcode of self.ssn since that is used
# for equality checks as well
return hash(self.ssn)
p = Person('Foo Bar', 123456789)
q = Person('Fake Name', 123456789)
print(len({p, q}) # 1
Run Code Online (Sandbox Code Playgroud)
集合需要两个方法来使对象可以使用:__hash__
和__eq__
.当两个实例被认为相等时,它们必须返回相同的哈希值.如果集合中存在散列且实例被认为等于集合中具有相同散列的实例之一,则认为实例已经存在于集合中.
您的类没有实现__eq__
,因此使用默认值object.__eq__
,如果obj1 is obj2
也为true ,则仅返回true.换句话说,如果两个实例是完全相同的实例,则它们仅被视为相等.
仅仅因为它们的哈希匹配,就一组而言,它们并不是唯一的; 即使具有不同散列的对象也可以在相同的散列表槽中结束,因为使用散列的模数与表大小相对应.
添加一个自定义__eq__
方法,该方法True
在两个实例应该相等时返回:
def __eq__(self, other):
if not isinstance(other, type(self)):
return False
# all instances of this class are considered equal to one another
return True
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7713 次 |
最近记录: |