Не удалось отсортировать список объектов в Python с помощью сравнения и lt - PullRequest
0 голосов
/ 30 мая 2019

Я не могу заставить этот код работать. Я пробовал то, что видел, просматривая сеть. Большинство показаний предлагают использовать __cmp__, но это не работает. Также я попытался использовать __lt__ с такими же неудачными результатами.

Может кто-нибудь следить за моим кодом и подсказать, как заставить его работать правильно?

Я создал класс Vertex (Vertice) с его инициализатором, методами __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()

Я ожидаю вывод списка вершин, во-первых упорядоченного по его координате "x", а во-вторых по его координате "y". В этот момент список переупорядочивается хаотично.

1 Ответ

1 голос
/ 03 июня 2019

Во-первых, как отмечено в Odds and Ends документации по сортировке:

Процедуры сортировки гарантированно будут использовать __lt__() при сравнении двух объектов.Таким образом, легко добавить стандартный порядок сортировки в класс, определив метод __lt__()

Это также упоминается в документации sort():

Этот метод сортирует список на месте, используя только <сравнения между элементами. </p>

Так что вам нужно только реализовать метод __lt__.
Вам не нужен __gt__ и __cmp__ больше не действительны для Python3 .

Далее, метод __lt__ должен возвращать либо True, либо False.

# 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...