简体   繁体   English

如何通过调用Python中的sort()方法来调用和处理__lt__方法?

[英]How is the method __lt__ invoked and processed by calling the method sort() in Python?

Executing this code: 执行此代码:

class Person(object):

    def __init__(self, name):
        self.name = name
        try:
            lastBlank = name.rindex(' ')
            self.lastName = name[lastBlank+1:]
        except:
            self.lastName = name

    def __lt__(self, other):
        if self.lastName == other.lastName:
            return self.name < other.name
        return self.lastName < other.lastName

    def __str__(self):
        return self.name

me = Person('Michael Guttag')
him = Person('Barack Hussein Obama')
her = Person('Madonna')
pList = [me, him, her]
pList.sort() #invoke __lt__()
for p in pList:
    print p

and it outputs: 它输出:

Michael Guttag
Madonna
Barack Hussein Obama

In the book where it exemplifies class and operator overloading (or polymorphism) it says: In addition to providing the syntactic convenience of writing infix expressions that use < , this overloading provides automatic access to any polymorphic method defined using __lt__ . 在该书中以类和运算符重载(或多态性)为例,它说:除了提供编写使用< infix表达式的语法方便之外,这种重载还提供对使用__lt__定义的任何多态方法的自动访问。 The built-in method sort is one such method. 内置方法分类就是这样一种方法。 So, for example, if pList is a list composed of elements of type Person , the call pList.sort() will sort that list using the __lt__ method defined in class Person . 因此,例如,如果pList是由Person类型的元素组成的列表,则调用pList.sort()将使用在Person类中定义的__lt__方法对该列表进行排序。

I don't understand how sort() is a polymorphic method (actually the concept of polymorphism is still unclear to me after lots of researching), and how the method __lt__ does the sorting to give such an output. 我不明白sort()是一种多态方法(实际上,经过大量研究后,我对多态性的概念仍然不清楚),以及方法__lt__如何进行排序以给出这样的输出。 I need a step-by-step guide. 我需要逐步指南。 Thank you! 谢谢!

The rich comparison methods - __lt__ , __le__ , __gt__ , __ge__ and __eq__ implement the various comparison operations. 丰富的比较方法__lt____le____gt____ge____eq__实现各种比较操作。 All of them compares two objects (one of them being self ). 它们都比较两个对象(其中一个是self )。 Together, they let you answer questions like "out of these two objects, which, if either, is bigger "? 它们一起使您可以回答诸如“在这两个对象中,哪一个更大 ,则更大 ”之类的问题? There are quite a few sorting algorithms that let you take a list of objects, and provided you can answer questions like that one on every pair of them, will let you put the whole list in the right order. 有很多排序算法可以让您列出对象列表,并且只要您可以在每个对象对上回答类似的问题,就可以按正确的顺序排列整个列表。 For example, one of the easier to understand ones is called selection sort - it works like this: 例如,一种更容易理解的方法称为选择排序-它的工作方式如下:

  1. Compare the first two items. 比较前两个项目。 Take the smallest (if they're equal, pick the first one), call it s 以最小的(如果他们是平等的,挑的第一个),称之为s
  2. Compare s to the next item that you haven't checked yet, and if that item is smaller, it is now s (otherwise, s is still the old s ) s与您尚未检查的下一个项目进行比较,如果该项目较小,则现在为s (否则, s仍然是旧s
  3. Do Step 2 repeatedly until you have no more items you haven't checked. 重复执行步骤2,直到没有更多未检查的项目为止。 This means s is now the smallest item in your list. 这意味着s现在是您列表中最小的项目。
  4. Move s to the start the list, shifting all the others up to fill the 'gap' where s was. s移动到列表的开头,将所有其他移动到s所在s “空白”。
  5. Consider the rest of the list (ie, excluding the first item), and run this whole process on that. 考虑列表的其余部分 (即,不包括第一项),并在此基础上运行整个过程。
  6. Keep going - excluding the first two, then the first three, and so on - until the remaining list only has one item. 继续前进-不包括前两个,然后是前三个,依此类推-直到其余列表只有一个项目。 The whole list is now sorted. 整个列表现在已排序。

Python's list.sort method runs a more complex, but faster, algorithm called Timsort . Python的list.sort方法运行一种更复杂但更快的算法,称为Timsort It achieves the same thing: given that you can know how any two elements are ordered relative to each other, it will sort the whole list for you. 它实现了同一件事:假定您可以知道两个元素之间的相对顺序,它将为您排序整个列表。

The details of how Timsort works aren't important - the point of using an existing method instead of writing your own is so you can just believe that it does work. Timsort的工作方式的细节并不重要-使用现有方法而不是编写自己的方法的意义在于,您可以相信它确实有效。 One thing that does matter is that nowhere in the documentation does it guarantee that it will use exactly < to compare each pair of elements - it is a good idea to implement at least __eq__ as well so that sort can know if two Person s happen to be equal. 一件很重要的事情是,文档中没有任何地方保证它会完全使用<来比较每对元素-最好也至少实现__eq__ ,这样sort才能知道两个Person是否发生了。等于。 You could write it like this: 您可以这样写:

def __eq__(self, other):
    return self.name == other.name

Once you've done that, there is a bit of builtin magic called functools.total_ordering that can fill in all the rest of the comparison methods for you. 完成此操作后,将有一些名为functools.total_ordering的内置魔术可以为您填充所有其他比较方法。 You can use it like this: 您可以像这样使用它:

import functools

@functools.total_ordering
class Person:
    ....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM