Reputation: 748
I'm having trouble comparing two list of objects in python
I'm converting a message into
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
Now when I create two lists of type StatusMessage
>>> expected = []
>>> expected.append(StatusMessage(1, "abc"))
>>> expected.append(StatusMessage(2, "bbc"))
>>> actual = []
>>> actual.append(StatusMessage(1, "abc"))
>>> actual.append(StatusMessage(2, "bbc"))
and then I compare the two lists using
>>> cmp(actual, expected)
or
>>> len(set(expected_messages_list).difference(actual_list)) == 0
I keep getting failures. When I debug and actually compare for each item within the list like
>>> actual[0].conversation_id == expected[0].conversation_id
>>> actual[0].platform == expected[0].platform
then I always see
True
Doing below returns -1
>>> cmp(actual[0], expected[0])
why is this so. What am I missing???
Upvotes: 3
Views: 1437
Reputation: 78690
You must tell python how to check two instances of class StatusMessage
for equality.
For example, adding the method
def __eq__(self,other):
return (self is other) or (self.conversation_id, self.platform) == (other.conversation_id, other.platform)
will have the following effect:
>>> cmp(expected,actual)
0
>>> expected == actual
True
If you want to use cmp
with your StatusMessage
objects, consider implementing the __lt__
and __gt__
methods as well. I don't know by which rule you want to consider one instance lesser or greater than another instance.
In addition, consider returning False
or error-checking for comparing a StatusMessage
object with an arbitrary object that has no conversation_id
or platform
attribute. Otherwise, you will get an 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'
You can find one reason why the self is other
check is a good idea here (possibly unexpected results in multithreaded applications).
Upvotes: 3
Reputation: 1165
Because you are trying to compare two custom objects, you have to define what makes the objects equal or not. You do this by defining the __eq__()
method on the StatusMessage
class:
class StatusMessage(object):
def __eq__(self, other):
return self.conversation_id == other.conversation_id and
self.platform == other.platform
Upvotes: 0