2015-04-23 17 views
11

Mam zagnieżdżonej listy, która zawiera różne obiekty, są zduplikowane pary obiektów na liście zagnieżdżonych i staram się je usunąć, ale trzymam corazJak sortować Python Przedmioty

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

znam ten błąd jest spowodowany przez mnie stara się pracować z obiektami zamiast 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) 
+2

przepustkę komparatora 'key' do' sorted' powinno działać. – Luca

Odpowiedz

6

Jeśli chcesz porównać obiektów przez id:

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 wdrożyć wszystkie rich comparison ordering methods można użyć functools.total_ordering, wystarczy określić jedną z metod i 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 

otrzymał klasa definiująca jedną lub więcej bogatych metod porównywania klas, dekorator klasy dostarcza resztę. Upraszcza to wysiłku związanego z określeniem wszystkich możliwych operacji bogaty porównania:

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

+0

Pierwsza opcja działa dla mnie ... Dzięki – danidee

+0

Nie ma problemu, właśnie dodałem drugi przykład, ponieważ może pomóc, jeśli chcesz dodać więcej funkcji później –

3

Wspieranie sortowania bez wyraźnych kluczy do obiektów w Pythonie 3, należy wdrożyć __lt__ specjalnej metody:

class practice: 
    id = None 

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

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

Jeśli chcesz innych podmiotów, do pracy, trzeba wdrożyć ich specjalne również metody, ale do sortowania jest wszystko, czego potrzebujesz.

Jak zauważył w komentarzach, drugi sposób to zrobić jest zapewnienie funkcji wyraźny klucz do sorted wbudowanym:

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

próbował użyć metody lambda, stworzyłem nową zmienną i utożsamiłem ją do posortowania (item, key = lambda x: x.id), ale kiedy próbuję wydrukować wartość, otrzymuję obiekt ćwiczeniowy nie jest iterowalny. czy to nie ma być lista? – danidee

+0

@danidee Pierwszy argument do posortowania musi być iteracją obiektów ćwiczeniowych. Więc spróbuj 'posortowane ([praktyka ('b'), praktyka (" a ')], klucz = lambda x: x.id) "na przykład. Zwróci ona nową listę w formie: "[praktyka (" a "), praktyka (" b ")]' – Shashank