Pytanie Jak sortować obiekty Pythona


Mam zagnieżdżoną listę, która zawiera różne obiekty, są to duplikaty par obiektów na liście zagnieżdżonej i próbuję je usunąć, ale nadal otrzymuję

TypeError: unorderable types: practice() < practice()

Wiem, że ten błąd jest spowodowany przez ja próbuję pracować z obiektami raczej niż liczb całkowitych, ale nie wiem jak inaczej usunąć duplikaty tutaj jest to, co próbowałem

class practice:
    id = None

    def __init__(self,id):
        self.id = id

a = practice('a')
b = practice('b')
c = practice('c')
d = practice('d')
e = practice('e')
f = practice('f')

x = [[a,b],[c,d],[a,b],[e,f],[a,b]]

unique_list = list()
for item in x:
    if sorted(item) not in unique_list:
        unique_list.append(sorted(item))

print(unique_list)

11
2018-04-23 00:41


pochodzenie


Podaj w komparatorze key do sorted powinno działać. - Luca


Odpowiedzi:


Jeśli chcesz porównać obiekty według identyfikatora:

class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return other.id > self.id

    def __gt__(self, other):
        return self.id > other.id

unique_list = list()
for item in x:
    if sorted(item) not in unique_list:
        unique_list.append(sorted(item))

print(unique_list)
[[<__main__.practice object at 0x7fe87e717c88>, <__main__.practice object at 0x7fe87e717cc0>],
 [<__main__.practice object at 0x7fe86f5f79e8>, <__main__.practice object at 0x7fe86f589278>],
 [<__main__.practice object at 0x7fe86f589be0>, <__main__.practice object at 0x7fe86f589c18>]]

W zależności od funkcji, którą chcesz zaimplementować bogate metody porządkowania porównań  możesz użyć functools.total_ordering, musisz tylko zdefiniować jedną z metod, a ona zajmie się resztą

from functools import total_ordering
@total_ordering
class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return other.id > self.id

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

Biorąc pod uwagę klasę definiującą jedną lub więcej bogatych metod porównywania, ten dekorator klasy dostarcza resztę. Upraszcza to wysiłek związany z określeniem wszystkich możliwych operacji porównania bogatego:

Klasa musi zdefiniować jedną z nich __lt__(), __le__(), __gt__(), lub __ge__(). Ponadto, klasa powinna dostarczyć __eq__() metoda.


6
2018-04-23 00:47



Pierwsza opcja zadziałała dla mnie ... Dzięki - danidee
Nie ma problemu, właśnie dodałem drugi przykład, ponieważ może pomóc, jeśli chcesz później dodać więcej funkcji - Padraic Cunningham


Aby obsługiwać sortowanie bez jawnych kluczy dla obiektów w Pythonie 3, musisz zaimplementować __lt__ specjalna metoda:

class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return self.id < other.id

Jeśli chcesz, aby inni operatorzy działali, będziesz musiał wdrożyć ich specjalne metody, ale także do sortowania __lt__ to wszystko, czego potrzebujesz.

Jak wspomniano w komentarzach, innym sposobem na to jest zapewnienie wyraźnej kluczowej funkcji sorted wbudowany:

sorted(item, key=lambda x: x.id)

3
2018-04-23 00:53



próbowałem użyć metody lambda, stworzyłem nową zmienną i utożsamiłem ją z sortowaniem (item, key = lambda x: x.id), ale gdy próbuję wydrukować wartość, otrzymuję obiekt ćwiczeniowy nie jest iterowalny. czy to nie ma być lista? - danidee
@danidee Pierwszym argumentem do posortowania musi być iteracja obiektów ćwiczeniowych. Więc spróbuj sorted([practice('b'), practice('a')], key=lambda x: x.id) na przykład. Zwróci nową listę w formularzu: [practice('a'), practice('b')] - Shashank