【发布时间】:2021-09-11 08:15:41
【问题描述】:
我觉得这个问题之前一定有人问过,但我找不到答案。
假设我想实现一个 Python 类,它的对象可以用sorted() 排序。我是否必须重新实现所有方法,如__lt__()、__gt__() 等?最低限度是多少?换句话说,sorted() 调用哪些方法进行排序?
【问题讨论】:
标签: python-3.x sorting redefinition
我觉得这个问题之前一定有人问过,但我找不到答案。
假设我想实现一个 Python 类,它的对象可以用sorted() 排序。我是否必须重新实现所有方法,如__lt__()、__gt__() 等?最低限度是多少?换句话说,sorted() 调用哪些方法进行排序?
【问题讨论】:
标签: python-3.x sorting redefinition
排序(*, key=None, reverse=False)
此方法对列表进行就地排序,仅使用项目之间的
所以你只需要为你的班级定义def __lt__(self,other):。
另请参阅底部附近的Sorting HOW-TO:
在两个对象之间进行比较时,排序例程保证使用
__lt__()。因此,很容易通过定义__lt__()方法为类添加标准排序顺序:
【讨论】:
sorted()是通过sort()实现的吗?
__lt__()。请参阅编辑以供参考。
只需要__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__ 的情况下工作。
【讨论】:
有一个 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)]
【讨论】: