Reputation: 23
I have a list of objects instantiated from a class. I need to sort the list using 'x' and 'is_start' parameters.
I tried using the total_ordering module from functools and custom wrote the lt & eq methods.
Class:
@total_ordering
class BuildingPoint(object):
def __init__(self):
self.x = None
self.height = None
self.is_start = None
def __lt__(self, other):
if self.x != other.x:
return self.x < other.x
def __eq__(self, other):
if self.x == other.x:
# If both points are starting points then building with higher height
# comes earlier
if self.is_start and other.is_start:
return self.height > other.height
# If both points are ending points then building with lower height
# comes earlier
if not self.is_start and not other.is_start:
return self.height < other.height
Now if I want to sort this list of BuildingPoint objects where the first and third objects have same x and is_start:
building_points = [[0, 2, True], [1, 2, False], [0, 3, True], [2, 3, False]]
Sorting building_points should give this output:
sorted(building_points)
>>[[0, 3, True], [0, 2, True], [1, 2, False], [2, 3, False]]
But it's returning the same object list. Any advice on how to do this?
Upvotes: 0
Views: 227
Reputation: 1514
As @juanpa.arrivillaga mentioned, your __lt__
and __eq__
were broken. I just fixed __lt__
and removed __eq__
, I think that's what you intended to do.
Also, you're sorting a list of arrays, not your BuildingPoint
object. I fixed your __init__
to create a BuildingPoint
from an array. And finally, I added a __repr__
method to be able to display the object.
I'm not sure if that's you want to do, here is what I did:
from functools import total_ordering
@total_ordering
class BuildingPoint(object):
def __init__(self,x,h,start):
self.x = x
self.height = h
self.is_start = start
def __repr__(self):
return "[{},{},{}]".format(self.x,self.height,self.is_start)
def __lt__(self, other):
if self.x != other.x:
return self.x < other.x
else:
if self.is_start and other.is_start:
return self.height > other.height
else:
return self.height < other.height
building_points = [ BuildingPoint(*array) for array in [[0, 2, True], [1, 2, False], [0, 3, True], [2, 3, False]]]
sorted(building_points)
Output:
[[0,3,True], [0,2,True], [1,2,False], [2,3,False]]
Upvotes: 1