使用比较和 lt 对 Python 中的对象列表进行排序失败

Fail in sorting a list of objects in Python using compare and lt

我无法使这段代码工作。我已经尝试过我在网上看到的内容。大多数迹象表明使用 __cmp__ 但它不起作用。另外,我试过使用 __lt__,结果同样不成功。

任何人都可以关注我的代码并告诉我如何让它正常工作吗?

我创建了一个顶点 class(顶点),它带有初始化程序、__lt____gt____cmp__ 方法。此外,一个创建 Vertex 列表并尝试对它们进行排序(未成功)的主程序。


class Vertice:
    def __init__(self, coordenada_x, coordenada_y):
        self.coordenada_x = coordenada_x
        self.coordenada_y = coordenada_y

    def __str__(self):
        return "Vértice ({},{})".format(self.coordenada_x, self.coordenada_y)

    def __add__(self, otro_vertice):
        vertice_resultado = Vertice(self.coordenada_x + otro_vertice.coordenada_x, self.coordenada_y + otro_vertice.coordenada_y)
        return vertice_resultado


    def __lt__(self, otro_vertice):
        if self.coordenada_x > otro_vertice.coordenada_x:
            return -1
        elif self.coordenada_x < otro_vertice.coordenada_x:
            return +1
        else:
            if self.coordenada_y > otro_vertice.coordenada_y:
                return -1
            elif self.coordenada_y < otro_vertice.coordenada_y:
                return +1
            else:
                return 0

    def __gt__(self, otro_vertice):
        if self.coordenada_x > otro_vertice.coordenada_x:
            return +1
        elif self.coordenada_x < otro_vertice.coordenada_x:
            return -1
        else:
            if self.coordenada_y > otro_vertice.coordenada_y:
                return +1
            elif self.coordenada_y < otro_vertice.coordenada_y:
                return -1
            else:
                return 0

    def __cmp__(self, otro_vertice):
        if self.coordenada_x > otro_vertice.coordenada_x:
            return +1
        elif self.coordenada_x < otro_vertice.coordenada_x:
            return -1
        else:
            if self.coordenada_y > otro_vertice.coordenada_y:
                return +1
            elif self.coordenada_y < otro_vertice.coordenada_y:
                return -1
            else:
                return 0

from Vertice import Vertice
import random

def main():
    lista = []
    for i in range(0,10):
        a = random.randint(1,99)
        b = random.randint(1,99)
        lista.append(Vertice(a,b))

    for elemento in lista:
        print(elemento)

    print()

    lista.sort()

    for elemento in lista:
        print(elemento)

    print()

main()

我希望 Vertex 列表的输出首先按 "x" 坐标排序,其次按 "y" 坐标排序。此时列表重新排序混乱。

首先,如 Odds and Ends 排序文档中所述:

The sort routines are guaranteed to use __lt__() when making comparisons between two objects. So, it is easy to add a standard sort order to a class by defining an __lt__() method

sort()文档中也提到了:

This method sorts the list in place, using only < comparisons between items.

所以你只需要实现一个__lt__方法。
你不需要 __gt____cmp__ is not anymore valid for Python3.

接下来,__lt__ 方法必须 return TrueFalse

# is self < other_vertice?
def __lt__(self, other_vertice):        
    if self.x > other_vertice.x:
        return False
    elif self.x < other_vertice.x:
        return True
    else:
        if self.y > other_vertice.y:
            return False
        elif self.y < other_vertice.y:
            return True
        else:
            return False

之后,您在 main 中的代码现在应该可以工作了:

def main():
    lista = []
    for i in range(0, 10):
        a = random.randint(1, 2)
        b = random.randint(1, 99)
        lista.append(Vertice(a, b))
    print("UNSORTED")
    for elemento in lista:
        print(elemento)

    print("SORTED")
    lista.sort()
    for elemento in lista:
        print(elemento)

main()

结果:

UNSORTED
Vértice (48,44)
Vértice (5,92)
Vértice (46,10)
Vértice (55,51)
Vértice (63,54)
Vértice (53,85)
Vértice (95,18)
Vértice (69,84)
Vértice (8,20)
Vértice (97,64)
SORTED
Vértice (5,92)
Vértice (8,20)
Vértice (46,10)
Vértice (48,44)
Vértice (53,85)
Vértice (55,51)
Vértice (63,54)
Vértice (69,84)
Vértice (95,18)
Vértice (97,64)

结果(当某些顶点具有相同的x时):

UNSORTED
Vértice (1,88)
Vértice (1,65)
Vértice (2,87)
Vértice (2,4)
Vértice (2,69)
Vértice (2,81)
Vértice (2,5)
Vértice (1,36)
Vértice (1,97)
Vértice (1,73)
SORTED
Vértice (1,36)
Vértice (1,65)
Vértice (1,73)
Vértice (1,88)
Vértice (1,97)
Vértice (2,4)
Vértice (2,5)
Vértice (2,69)
Vértice (2,81)
Vértice (2,87)