要重新定义哪些Python对象比较方法才能使sorted()工作



我觉得这个问题以前一定被问过,但我找不到答案。

假设我想要实现一个Python类,该类的对象可以用sorted()进行排序。我必须重新实现__lt__()__gt__()等所有方法吗。?最低限度是多少?换句话说,sorted()调用哪种方法进行排序?

根据文档:

排序(*,key=None,reverse=False(
此方法对列表进行适当排序,只使用<项目之间的比较。异常不会被抑制-如果任何比较操作失败,整个排序操作将失败(列表可能会处于部分修改状态(。

所以您只需要为类定义def __lt__(self,other):

另请参阅底部附近的排序HOW-TO:

在两个对象之间进行比较时,保证排序例程使用__lt__()。因此,通过定义一个__lt__()方法可以很容易地将标准排序顺序添加到类中:

有一个functools内置方法total_ordering,它可以修饰类,并使其实例能够在没有关键函数规范的情况下传递给sorted((。

该类的唯一要求是定义任何一个比较dunder方法和__eq__

例如:

from functools import total_ordering
@total_ordering
class Sortable:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return self.x, self.y

def __lt__(self, obj):
return self.y < obj.y
def __eq__(self, obj):
return self.y == obj.y
obj_1 = Sortable("Hello", 9)
obj_2 = Sortable("World", -2)
obj_3 = Sortable("!", 5.5)
print(sorted([obj_1, obj_2, obj_3])

哪个输出:

>>> [("World", -2), ("!", 5.5), ("Hello", 9)]

只需要__lt__。参见以下示例:

class MyCustomNumber:
def __init__(self, some_number):
self.some_number = some_number
def __lt__(self, other):
return self.some_number < other.some_number

list_ = [MyCustomNumber(1), MyCustomNumber(5), MyCustomNumber(-3), MyCustomNumber(150)]
for x in sorted(list_):
print(x.some_number)

输出:

-3
1
5
150

即使是sorted(list_, reverse=True)也只能在实现__lt__的情况下工作。

最新更新