Ric*_*d J 16 python dictionary
我试图将一个对象用作python字典中的一个键,但它的表现方式我无法理解.
首先,我创建一个以对象为关键字的字典:
package_disseminators = {
ContentType("application", "zip", "http://other/property") : "one",
ContentType("application", "zip") : "two"
}
Run Code Online (Sandbox Code Playgroud)
现在创建另一个与关键对象"相同"的对象.
content_type = ContentType("application", "zip", "http://other/property")
Run Code Online (Sandbox Code Playgroud)
我已经为ContentType对象提供了自定义__eq__
和自定义__str__
方法,以便该__eq__
方法比较这些__str__
值.
现在,一些交互式python:
>>> for key in package_disseminators:
... if key == content_type:
... print "match"
... else:
... print "no match"
...
no match
match
>>> content_type in package_disseminators.keys()
True
Run Code Online (Sandbox Code Playgroud)
好的,所以看起来我的对象肯定被正确识别为一个键,所以:
>>> package_disseminators[content_type]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: (& (type="application/zip") (packaging="http://other/property") )
Run Code Online (Sandbox Code Playgroud)
呃......好吗?所以content_type在package_disseminators.keys()列表中,但不是密钥?
>>> package_disseminators.has_key(content_type)
False
Run Code Online (Sandbox Code Playgroud)
显然不是.
我假设Python用来确定相等性的比较过程在列表上的直接"in"语句和实际查找dict中的键之间有所不同,但我不知道如何.任何提示或见解?
Rei*_*cke 26
从python文档:
字典的键几乎是任意值.不可清除的值,即包含列表,字典或其他可变类型(通过值而不是按对象标识进行比较)的值不能用作键.
Hashable定义如下
一个目的是可哈希如果它有一个哈希值其寿命(它需要一个在这期间从不改变
__hash__()
方法),并且可相对于其他对象(它需要一个__eq__()
或__cmp__()
方法).比较相等的可哈希对象必须具有相同的哈希值.Hashability使对象可用作字典键和set成员,因为这些数据结构在内部使用哈希值.
因此,如果您想这样做,您需要覆盖__hash__()
对象的默认方法(请参阅下面的Steven Rumbalski的评论以获得进一步的解释).
>>> content_type in package_disseminators.keys()
True
Run Code Online (Sandbox Code Playgroud)
我认为这是有效的,因为dict.keys()
返回一个列表,__contains__
可能会检查相等性,但不会检查相同的哈希值.
nos*_*klo 20
由于dicts是引擎盖下的哈希表,因此您需要定义两者__eq__
并__hash__
为此工作.
基本的经验法则是:
__eq__
比较相等的对象,__hash__
必须返回相同的哈希.从你的描述,像
def __hash__(self):
return hash(str(self))
Run Code Online (Sandbox Code Playgroud)
应该管用.