输入dict和输入key之间有什么区别听写键()?

2024-04-20 11:38:01 发布

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

我最近在使用python 2.7时遇到了一个问题:

class A(object):
    def __init__(self, v):
        self.v = v

    def __eq__(self, other):
        return self.v == other.v

a1 = A(1)
a2 = A(1)

所以:

print a1 == a2  # True

以及:

d = {a1: 1}
print a2 in d.keys()  # True

但是:

print a2 in d  # False

问题是a2 ind.keys()a2 in d之间的主要区别是什么?如何获得a2 in d is True?你知道吗


Tags: inselffalsetruea2returnobjectinit
1条回答
网友
1楼 · 发布于 2024-04-20 11:38:01

在Python2.7中,dict.keys返回一个键列表,a2 in d.keys()将线性迭代所有键,以确定a2是否在列表中。你知道吗

但是a2 in d将根据对象a2的散列值在字典中执行O(1)查找,以查看键a2是否在d。你知道吗


但在你的情况下,问题是完全不同的。引用official documentation

If a class does not define a __cmp__() or __eq__() method it should not define a __hash__() operation either; if it defines __cmp__() or __eq__() but not __hash__(), its instances will not be usable in hashed collections. If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__(), since hashable collection implementations require that a object’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).

因为您没有显式定义__hash__函数,所以您正在破坏它们之间的契约,__hash__使用基于对象的^{}的默认哈希,这对于a1a2都是不同的。因此,即使a1a2是相似的,散列对象也会将它们视为两个不同的对象,因为它们的散列值是不同的。你知道吗

要解决这个问题,需要定义__hash__函数,如下所示

class A(object):

    def __init__(self, v):
        self.v = v

    def __eq__(self, other):
        return self.v == other.v

    def __hash__(self):
        return hash(self.v)

a1 = A(1)
a2 = A(1)

d = {a1: 1}
print a2 in d.keys()  # True
print a2 in d         # True

相关问题 更多 >