在Python中使用的Dict.get是比较dict中的键吗?

时间:2014-12-19 14:50:36

标签: python python-2.7 dictionary

我使用Python2.7编写Set数据结构。但是在使用Dict.get时我很困惑。这是我的代码:

#!/usr/bin/env python
# -*- coding:UTF-8
__author__ = 'shenshijun'


class Node(object):
    def __init__(self, key, weight):
        """Constructor for """
        self.key = key
        self.weight = weight

    def __cmp__(self, other):
        return cmp(self.key, other.key)

    def __str__(self):
        return "".join(['Node(key=', str(self.key), ',weight=', str(self.weight), ")"])


__dict = {}
a1 = Node('A', 1)
a2 = Node('A', 2)
__dict[a1] = a1
print a1 == a2
print(__dict.get(a2))

此代码的输出如下:

True     None

所以我猜Python在搜索时使用is运算符来比较键。有人可以找到真相吗?

我使用的Python:

2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]

我刚刚解决了我的问题,但有关在这种情况下如何实施__hash__的任何建议?

2 个答案:

答案 0 :(得分:2)

你在a1和a2上有一个相等,但是它们不是同一个对象,实际上引用已经改变了,所以

print a1 is a2  # False
print(__dict.get(a1)) # Node(key=A,weight=1)
print(__dict.get(a2)) # None

a1与a2不是同一个对象,a1的键引用节点,但不引用a2。

编辑

正如@tobias_k所说,您可以覆盖__hash__函数以执行不同的方式来存储哈希引用而不是内存地址,例如:

class Node(object):
    def __init__(self, key, weight):
        """Constructor for """
        self.key = key
        self.weight = weight

    def __cmp__(self, other):
        return cmp(self.key, other.key)

    def __str__(self):
        return "".join(['Node(key=', str(self.key), ',weight=', str(self.weight), ")"])

    def __hash__(self):
        return ord(self.key)

__dict = {}
a1 = Node('A', 1)
a2 = Node('A', 2)
__dict[a1] = a1
print a1 == a2 # True
print a1 is a2 # False 
print(__dict.get(a1)) # Node(key=A,weight=1)
print(__dict.get(a2)) # Node(key=A,weight=1)

答案 1 :(得分:2)

当您在dictionary中查找某个键时,它不会立即测试是否相等。首先,它检查哈希码,以确定"桶"如果项目应该,那么 它将检查是否相等。

由于你没有实现__hash__方法,它使用默认的哈希码,即内存地址IIRC,所以它从不首先检查相等性。将此添加到您的课程,然后它将工作

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

输出:

True
Node(key=A,weight=1)

您还可以向print__hash__函数添加一些__cmp__语句,以查看这些语句的调用时间和顺序。


附录:值得注意的是,虽然没有编程语言强制要求,但在实施{{1}时总是实施__hash__或者__eq__,并且以这样的方式,每当两个对象相等时,它们也具有相同的哈希码(反过来不是必需的)。

有关更多信息,请参阅this related question(对于Java,但对Python有效)。