对象作为python字典中的键 [英] objects as keys in python dictionaries
问题描述
我正在尝试将对象用作python字典中的键,但是它的行为方式我不太了解.
I'm trying to use an object as a key in a python dictionary, but it's behaving in a way that I can't quite understand.
首先,我创建一个以对象为键的字典:
First I create a dictionary with my object as the key:
package_disseminators = {
ContentType("application", "zip", "http://other/property") : "one",
ContentType("application", "zip") : "two"
}
现在创建另一个与键相同的对象.
Now create another object that is "the same" as one which is a key.
content_type = ContentType("application", "zip", "http://other/property")
我为ContentType对象提供了自定义__eq__
和自定义__str__
方法,以便__eq__
方法比较__str__
值.
I have given the ContentType object custom __eq__
and custom __str__
methods, such that the __eq__
method compares the __str__
values.
现在,一些交互式python:
Now, some interactive 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
好,所以看来我的对象肯定可以正确地识别为钥匙,所以:
Ok, so it looks like my object is definitely being identified properly as a key, so:
>>> package_disseminators[content_type]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: (& (type="application/zip") (packaging="http://other/property") )
嗯...好吗?因此content_type在package_disseminators.keys()列表中,但不是键吗?
Er ... ok? So content_type is in the package_disseminators.keys() list, but isn't a key?
>>> package_disseminators.has_key(content_type)
False
显然不是.
我认为Python用于确定相等性的比较过程在列表上的直接"in"语句和实际在dict中查找键之间是不同的,但是我不知道该怎么做.有提示或见解吗?
I presume that the comparison process that Python uses to determin equality differs between a straight "in" statement on a list and actually looking up a key in a dict, but I don't know how. Any tips or insights?
推荐答案
来自python文档:
From the python documentation:
字典的按键几乎 任意值.不等于的值 可散列的,即包含 列表,字典或其他可变的 类型(按值进行比较 而不是通过对象标识) 不能用作键.
A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may not be used as keys.
可哈希的定义如下
如果对象具有哈希,则该对象是可哈希的 在其过程中永不改变的价值 生命周期(需要
__hash__()
方法),并且可以与其他方法进行比较 对象(需要__eq__()
或__cmp__()
方法).比较相等的可哈希对象必须具有相同的值 哈希值.
An object is hashable if it has a hash value which never changes during its lifetime (it needs a
__hash__()
method), and can be compared to other objects (it needs an__eq__()
or__cmp__()
method). Hashable objects which compare equal must have the same hash value.
可哈希性使对象可用作 一个字典键和一个set成员, 因为这些数据结构使用 内部哈希值.
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
因此,如果要执行此操作,则需要在对象上覆盖默认的__hash__()
方法(有关详细说明,请参见下面的Steven Rumbalski的评论).
So if you want to do this, you need to override the default __hash__()
method on your object (see the comment from Steven Rumbalski below for further explanation).
>>> content_type in package_disseminators.keys()
True
我认为这是可行的,因为dict.keys()
返回一个列表,并且__contains__
可能会检查是否相等,但不会检查相同的散列.
I suppose this works because dict.keys()
returns a list, and __contains__
probably checks for equality, but not for the same hashes.
这篇关于对象作为python字典中的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!