【问题标题】:Which Python object comparison methods to redefine to make sorted() work?要重新定义哪些 Python 对象比较方法以使 sorted() 起作用?
【发布时间】:2021-09-11 08:15:41
【问题描述】:

我觉得这个问题之前一定有人问过,但我找不到答案。

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

【问题讨论】:

    标签: python-3.x sorting redefinition


    【解决方案1】:

    根据documentation

    排序(*, key=None, reverse=False)
    此方法对列表进行就地排序,仅使用项目之间的

    所以你只需要为你的班级定义def __lt__(self,other):

    另请参阅底部附近的Sorting HOW-TO

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

    【讨论】:

    • 但是sorted()是通过sort()实现的吗?
    • @DYZ Python 排序例程都使用__lt__()。请参阅编辑以供参考。
    【解决方案2】:

    只需要__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__ 的情况下工作。

    【讨论】:

      【解决方案3】:

      有一个 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)]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        相关资源
        最近更新 更多