0xC*_*22L 3 python collections hash dictionary python-2.x
我想编写一个可以用作可散列集合中的键的类(例如,在a中dict
).我知道用户类默认id(self)
是可以使用的,但在这里使用是错误的.
我的类拥有一个tuple
as成员变量.派生tuple
似乎不是一个选项,因为在我的构造函数中,我没有得到与构造函数相同的参数tuple
.但也许这不是限制?
我需要的基本上是tuple
一个真正的元组给它的方式的哈希.
hash(self.member_tuple)
做到了那一点.
这里的想法是两个元组可以相等而不id
相等.
如果我__cmp__()
按如下方式执行:
def __cmp__(self, other):
return cmp(self, other)
Run Code Online (Sandbox Code Playgroud)
这会自动求助于hash(self)
比较吗?......或者我应该按如下方式实施:
def __cmp__(self, other):
return cmp(self.member_tuple, other)
Run Code Online (Sandbox Code Playgroud)
我的__hash__()
函数被实现为返回被保持的哈希值tuple
,即:
def __hash__(self):
return hash(self.member_tuple)
Run Code Online (Sandbox Code Playgroud)
基本上,如何做__cmp__()
和__hash__()
互动?我不知道是否__cmp__()
该other
将已经是一个哈希与否,我是否应该比较对"我"的哈希(这将是的举行的一个tuple
),或反对self
.
那么哪一个是正确的呢?
任何人都可以对此有所了解并可能指出我的文档吗?
我不会使用__cmp__
并坚持使用__eq__
.对于散列是足够的,你不想扩展到这里可排序.此外,__cmp__
已经从Python 3的赞成富比较方法(除去__eq__
,__lt__
,__gt__
等等).
接下来,__eq__
当成员元组相等时,您应该返回True:
def __eq__(self, other):
if not isinstance(other, ThisClass):
return NotImplemented
return self.member_tuple == other.member_tuple
Run Code Online (Sandbox Code Playgroud)
NotImplemented
当other
对象的类型不相同时返回单例是很好的做法,因为它会将相等测试委托给other
对象; 如果它没有实现__eq__
或者也返回NotImplemented
Python将回退到标准id()
测试.
您的__hash__
实施是正确的.
因为哈希不是唯一的(它只是在哈希表中选择一个槽的一种方法),所以使用相等来确定匹配键是否已经存在或者是否发生了哈希冲突.作为这种__eq__
(或__cmp__
如果__eq__
丢失)不如果要将对象被散列化槽是空的调用.
这意味着如果两个对象被认为是相等的(a.__eq__(b)
返回True
),那么它们的哈希值也必须相等.否则,您最终可能会损坏字典,因为Python将无法再确定哈希表中是否已存在密钥.
如果您__eq__
和__hash__
方法都将其职责委托给self.member_tuple
属性,那么您将维护该属性; 您可以信任基本tuple
类型以正确实现此功能.
请参阅hashable的术语表定义和object.__hash__()
文档.如果你很好奇,我已经写过内部dict
和set
类型如何工作:
归档时间: |
|
查看次数: |
1162 次 |
最近记录: |