使用类参数中的条件对类对象列表进行排序

时间:2019-06-24 01:27:58

标签: python sorting functools

我有一个从类实例化的对象列表。我需要使用'x'和'is_start'参数对列表进行排序。

我尝试使用functools中的total_ordering模块,并自定义编写lt&eq方法。

班级:

@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

现在,如果我要对以下第一个和第三个对象具有相同的x和is_start的BuildingPoint对象列表进行排序:

building_points = [[0, 2, True], [1, 2, False], [0, 3, True], [2, 3, False]]

排序building_points应该提供以下输出:

sorted(building_points)
>>[[0, 3, True], [0, 2, True], [1, 2, False], [2, 3, False]]

但是它返回相同的对象列表。有关如何执行此操作的任何建议?

1 个答案:

答案 0 :(得分:1)

正如@ juanpa.arrivillaga所述,您的__lt____eq__已损坏。我只是固定了__lt__并删除了__eq__,我认为这就是您要执行的操作。 另外,您正在对数组列表进行排序,而不是对BuildingPoint对象的排序。我修复了您的__init__,从数组中创建了BuildingPoint。最后,我添加了一个__repr__方法来显示对象。

我不确定这是否是您想要的,这就是我所做的:

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)

输出:

[[0,3,True], [0,2,True], [1,2,False], [2,3,False]]