比较两个自定义列表python

时间:2016-02-01 19:16:02

标签: python list compare

我在比较python

中的两个对象列表时遇到了问题

我将邮件转换为

class StatusMessage(object):
    def __init__(self, conversation_id, platform):
        self.__conversation_id = str(conversation_id)
        self.__platform = str(platform)

    @property
    def conversation_id(self):
        return self.__conversation_id

    @property
    def platform(self):
        return self.__platform 

现在我创建了两个StatusMessage类型的列表

>>> expected = []
>>> expected.append(StatusMessage(1, "abc"))
>>> expected.append(StatusMessage(2, "bbc"))

>>> actual = []
>>> actual.append(StatusMessage(1, "abc"))
>>> actual.append(StatusMessage(2, "bbc"))

然后我使用

比较两个列表
>>> cmp(actual, expected) 

>>> len(set(expected_messages_list).difference(actual_list)) == 0

我一直都在失败。 当我调试并实际比较列表中的每个项目时,如

>>> actual[0].conversation_id == expected[0].conversation_id
>>> actual[0].platform == expected[0].platform

然后我总是看到

True

执行以下操作会返回-1

>>> cmp(actual[0], expected[0])

为什么会如此。我错过了什么?

2 个答案:

答案 0 :(得分:3)

你必须告诉python如何检查类StatusMessage的两个实例是否相等。

例如,添加方法

def __eq__(self,other):
    return (self is other) or (self.conversation_id, self.platform) == (other.conversation_id, other.platform)

会产生以下影响:

>>> cmp(expected,actual)
0
>>> expected == actual
True

如果您想将cmpStatusMessage个对象一起使用,请考虑实施__lt____gt__方法。我不知道您想要将一个实例视为小于或大于另一个实例的规则。

此外,请考虑返回False或错误检查,以便将StatusMessage对象与没有conversation_idplatform属性的任意对象进行比较。否则,您将获得AttributeError

>>> actual[0] == 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "a.py", line 16, in __eq__
    return (self is other) or (self.conversation_id, self.platform) == (other.conversation_id, other.platform)
AttributeError: 'int' object has no attribute 'conversation_id'

您可以找到self is other检查是个好主意here的一个原因(多线程应用程序中可能出现意外结果)。

答案 1 :(得分:0)

因为您正在尝试比较两个自定义对象,所以必须定义使对象相等或不相等的内容。您可以通过在__eq__()类上定义StatusMessage方法来执行此操作:

class StatusMessage(object):
    def __eq__(self, other):
        return self.conversation_id == other.conversation_id and
               self.platform == other.platform