对象作为python字典中的键 [英] objects as keys in python dictionaries

查看:272
本文介绍了对象作为python字典中的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将对象用作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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆