什么是Java中可比较的Python等价物?

时间:2011-08-05 09:54:06

标签: python

我有以下表格的字典:

{ <Category('Simulate', 'False', 'False', 'False', 'INTERMEDIATE')>: {'link': u'/story/4/tvb-adapters-simulator-simulatorAdapter/SimulatorAdapter', 'name': u'Simulate'}, 
  <Category('View Results', 'True', 'False', 'True', 'INTERMEDIATE')>: {'link': '/story/step/3', 'name': u'View Results'}, 
  <Category('Analyze', 'True', 'False', 'False', 'FINAL')>: {'link': '/story/step/2', 'name': u'Analyze'}}

Category是一个表示数据库中实例的类。现在我有以下实例:

    <Category('Analyze', 'True', 'False', 'False', 'FINAL')>

现在这不是同一个实例。我的意思是,我从数据库中获取所有值并创建字典。然后过了一会儿我得到一个id并从数据库中检索实例。现在他们不是同一个对象。我现在必须检查它是否在字典中,但是:

instance in disctionary

将返回false。现在我可以采用丑陋的方式迭代字典检查所有值是否匹配,但是Python有更聪明的方法吗?我的意思是类似于Java中的Comparable?

5 个答案:

答案 0 :(得分:12)

首先:使用TrueFalse(布尔属性)而不是'True''False'(字符串属性)。

通常,您可以在Python中使所有内容都具有可比性。您只需为您的班级定义特定方法(例如__eq____lt__等)。

所以,假设我想要比较A类的实例,并且比较应该只是s成员的不区分大小写的字符串比较:

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

    def __eq__(self, other):
        return self.s.lower() == other.s.lower()

a = A('aaaa')
b = A('AAAA')
print a == b # prints True
b = A('bbbb')
print a == b # prints False

答案 1 :(得分:2)

而不是使用Category的实例(例如Category('Analyze', 'True', 'False', 'False', 'FINAL'))作为词典中的键, 听起来你应该使用相关的元组(例如('Analyze', 'True', 'False', 'False', 'FINAL'))。

如果您确实想要使用Category的实例作为字典中的键,则需要同时定义__hash____eq__方法。 例如:

class Category(object):
    def __init__(self,*args):
        self.args=args
    def __hash__(self):
        # Note that this assumes that Category's hash value is immutable
        # i.e. self.args does not change.
        return hash(self.args)
    def __eq__(self,other):
        return self.args == other.args

a=Category('Analyze', 'True', 'False', 'False', 'FINAL')
b=Category('Analyze', 'True', 'False', 'False', 'FINAL')

mydict={a:1}

ab是不同的实例,因此它们具有不同的id s,但它们的哈希值是相同的:

assert id(a) != id(b)
assert hash(a)==hash(b)

这表明b中的mydict是可接受的密钥:

print(mydict[a])
# 1
print(mydict[b])
# 1

PS。不要打扰__cmp__In Python 3

  

应该将cmp()函数视为已消失,__cmp__()   不再支持特殊方法。使用__lt__()进行排序,   __eq__() __hash__() {{1}},以及其他必要的丰富比较。

答案 2 :(得分:2)

由于您显然可以将类别实例放入dict中,因此必须已覆盖__hash__。您现在需要的只是__eq__

class Category(object):
    # you must have overwritten `__hash__` like this already
    def __hash__(self):
        return hash((self.attr1, self.attr2, ... ))

    # now you just need tis
    def __eq__(self, other):
        return isinstance(other, Category) and \
               (self.attr1, self.attr2, ... ) == (other.attr1, other.attr2, ... )

你真正要做的就是抛弃整个班级而改为使用collections.namedtuple

Category = collections.namedtuple('Category', 'attr1 attr2 attr3')

答案 3 :(得分:1)

可能有快捷方式,例如使用元组,但对您的问题的一般答案是:为您的类实现__eq__(),以便cmp()将使用它而不是测试身份。

答案 4 :(得分:1)

要使in和其他比较运算符起作用,您必须实现__hash____cmp__(或“{”1}}之类的“丰富”比较方法。请参阅Python reference