Python字典中的对象为键

2024-04-29 13:02:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在python字典中使用一个对象作为键,但是它的行为方式让我无法完全理解。

首先,我创建一个以对象为键的字典:

package_disseminators = {
  ContentType("application", "zip", "http://other/property") : "one",
  ContentType("application", "zip") : "two"
}

现在创建另一个对象,该对象与一个键“相同”。

content_type = ContentType("application", "zip", "http://other/property")

我已经给了ContentType对象custom__eq__和custom__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

好吧,看来我的对象被正确地识别为一个密钥,所以:

>>> 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_displaminators.keys()列表中,但它不是一个键吗?

>>> package_disseminators.has_key(content_type)
False

显然不是。

我假设Python用于确定相等性的比较过程在列表上的直接“in”语句和实际在dict中查找键之间是不同的,但我不知道如何实现。有什么建议或见解吗?


Tags: 对象keyinhttppackage字典applicationtype
2条回答

从python文档中:

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.

Hashable定义如下

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.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

因此,如果您想这样做,您需要重写对象上的默认__hash__()方法(请参阅下面史蒂文·伦巴尔斯基的注释以获得进一步的解释)。


>>> content_type in package_disseminators.keys()
True

我想这是可行的,因为dict.keys()返回一个列表,并且__contains__可能检查等式,但不检查相同的散列。

由于dict是隐藏的哈希表,因此需要同时定义__eq____hash__才能工作。

基本经验法则是:

  • 对于__eq__比较相等的对象,__hash__必须返回相同的哈希。

从你的描述来看

def __hash__(self):
    return hash(str(self))

应该有用。

相关问题 更多 >