2015-04-23 29 views
11

Ho un elenco nidificato che contiene diversi oggetti, sono coppie duplicati di oggetti nella lista annidata e sto cercando di rimuoverli, ma continuo a ricevere unCome ordinare Python Oggetti

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

so che questo errore è causato da me cercando di lavorare con gli oggetti, piuttosto che gli interi, ma non so in quale altro modo per rimuovere i duplicati Ecco quello che ho provato

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

Passo in un comparatore 'key' a' sorted' dovrebbe funzionare. – Luca

risposta

6

Se si desidera confrontare gli oggetti da parte del 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>]] 

A seconda delle funzionalità che si desidera implementare tutte le rich comparison ordering methods è possibile utilizzare functools.total_ordering, basta a definire uno dei metodi e si prenderà cura di tutto il resto

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 

Dato un classe che definisce uno o più metodi di ordine di confronto ricco, questo decoratore di classe fornisce il resto. Questo semplifica lo sforzo di specificare tutte le possibili operazioni ricco di confronto:

La classe deve definire uno dei __lt__(), __le__(), __gt__() o __ge__(). Inoltre, la classe deve fornire un metodo __eq__().

+0

La prima opzione ha funzionato per me ... Grazie – danidee

+0

No prob, ho appena aggiunto il secondo esempio in quanto potrebbe essere di aiuto se si desidera aggiungere più funzionalità in seguito –

3

Per supportare l'ordinamento senza chiavi esplicite per gli oggetti in Python 3, è necessario implementare il __lt__ metodo speciale:

class practice: 
    id = None 

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

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

Se si desidera che gli altri operatori di lavorare, si dovrà attuare il loro speciale anche i metodi, ma per lo smistamento __lt__ è tutto ciò che serve.

Come notato nei commenti, l'altro modo per farlo è quello di fornire una funzione chiave esplicito al sorted built-in:

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

si stava tentando di utilizzare il metodo lambda, ho creato una nuova variabile e l'ho equiparata per ordinare (item, key = lambda x: x.id) ma quando provo a stampare il valore, ottengo che l'oggetto di esercitazione non è iterable. non dovrebbe essere una lista? – danidee

+0

@danidee Il primo argomento da ordinare deve essere un iterable di oggetti di esercitazione. Quindi prova 'ordinato ([practice ('b'), practice ('a')], key = lambda x: x.id)' per esempio. Restituirà una nuova lista nel formato: '[practice ('a'), practice ('b')]' – Shashank