使用 class 参数中的条件对 class 对象列表进行排序
Sorting a list of class objects using conditions in class parameters
我有一个从 class 实例化的对象列表。我需要使用 'x' 和 'is_start' 参数对列表进行排序。
我尝试使用 functools 中的 total_ordering 模块并自定义编写了 lt 和 eq 方法。
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
现在,如果我想对第一个和第三个对象具有相同 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]]
但它返回相同的对象列表。关于如何做到这一点的任何建议?
如@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]]
我有一个从 class 实例化的对象列表。我需要使用 'x' 和 'is_start' 参数对列表进行排序。
我尝试使用 functools 中的 total_ordering 模块并自定义编写了 lt 和 eq 方法。
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
现在,如果我想对第一个和第三个对象具有相同 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]]
但它返回相同的对象列表。关于如何做到这一点的任何建议?
如@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]]