在Java中,Python等价于可比数据是什么?

2024-09-19 20:50:53 发布

您现在位置: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?


Tags: 实例nameview数据库falsetrue字典step
3条回答

首先:使用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

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

如果您确实想使用Category的实例作为字典中的键,则需要同时定义^{}__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是不同的实例,因此它们具有不同的ids,但它们的哈希值相同:

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

这表明bmydict中可接受的键:

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

另外,不用担心__cmp__In Python 3

The cmp() function should be treated as gone, and the __cmp__() special method is no longer supported. Use __lt__() for sorting, __eq__() with __hash__(), and other rich comparisons as needed.

显然,您可以将类别实例放入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')

相关问题 更多 >