使用自定义对象查询Python字典键

时间:2012-05-31 22:29:11

标签: python dictionary

考虑使用下面类对象创建的键的字典:

class Point( object ):

    def __init__( self, x, y ):
        self.x = x
        self.y = y

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

    def __hash__( self ):
        return self.x.__hash__()

    def __ne__( self, other ):
        return self.x != other.x

>>> a = Point(1,1)
>>> b = Point(0, 2)
>>> dct = {}
>>> dct[a] = 15
>>> dct[b] = 16
>>> dct[a]
15
>>> c = Point(1,None)
>>> dct[c]
15

这是因为ca共享相同的哈希并且相等。是否有一种O(1)方法来实现给定c返回a的函数(与下面的O(n)实现相反?):

def getKey( dct, key ):
    for k in dct:
        if k == key:
            return k
    return None

4 个答案:

答案 0 :(得分:2)

你的功能总是返回,所以我不明白你的意思......

根据复杂性,假设您至少需要O(log(n)), 例如,如果dct是我想的字典,那么:

def getKey( dct, key ):
    if dct.has_key(key):
        return key
    return None

如果你想返回它的值,那么只需使用: dct.get(key,None)

答案 1 :(得分:1)

您可以将字典的值设置为由元组和值本身组成的元组或列表。使用你的例子:

>>> a = Point(1,1)
>>> b = Point(0, 2)
>>> dct = {}
>>> dct[a] = (15, a)
>>> dct[b] = (16, b)
>>> dct[a] 
(15, <Point object at 0xb769dc2c>)
>>> c = Point(1,None)
>>> dct[c]
(15, <Point object at 0xb769dc2c>)

现在您可以a使用c获取>>> dct[c][1]

{{1}}

答案 2 :(得分:1)

  

这是因为c和a共享相同的哈希值。

没有;之所以会发生这种情况,是因为它们共享哈希比较相等。

通常,不相等的对象可以散列为相同的值。 (等于必须哈希到相同的值。)

如果对象具有相同的x坐标,则__eq__将对象定义为相等。这显然是错的;如果两个坐标相等,它们应该相等。

但听起来这并不是你真正想做的事情。如果你想“给c,得到a”,那么你真正要问的是,给定一个点,找到具有相同x坐标的所有其他点。

这很简单:制作一个dict,将x坐标值映射到带有该坐标的点。

答案 3 :(得分:0)

换句话说,给定一个对象列表和一个对象X,找到列表中与X具有相同散列值的元素。考虑:

class A(object):
    def __init__(self, x, blah):
        self.x = x
        self.blah = blah
    def __eq__(self, other):
        return self.x == other.x
    def __hash__(self):
        return self.x
    def __repr__(self):
        return '%d-%s' % (self.x, self.blah)


ls = [A(1, 'one'), A(2, 'FOO'), A(3, 'three')]
test = A(2, 'BAR')
print test, '=', (set(ls) - (set(ls) - set([test]))).pop()

要使用字典示例,请将set(ls)替换为viewkeys

dct = dict(zip(ls, range(100)))
print test, '=', (dct.viewkeys() - (dct.viewkeys() - set([test]))).pop()