Liste nach Attributen sortieren...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

ich möchte eine Liste 'entries' mit Entry()-Exemplaren nach einem bestimmten Attribut sortieren. Folgendes funktioniert, wenn die Exemplare eine Methode 'get_title()' besitzen:

Code: Alles auswählen

sorted(entries, key=Entry.get_title)
Ich würde aber etwas in der Art, allerdings ohne den Umweg über ein lambda, bevorzugen:

Code: Alles auswählen

sorted(entries, key=lambda e: getattr(e, 'title'))
Was könnte ich machen?

Gruß
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Bei sorted kannst du doch auch eine Comparison Funktion angeben, die das Vergleichen übernimmt. Oder, das musst du aber testen, du implementierst __lt__, __gt__ usw. auf dem Objekt
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Das Leben ist wie ein Tennisball.
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Code: Alles auswählen

class Itr(object):
    def __init__(self, val):
        self.cmp = val
        
    def __gt__(self, other):
        return self.cmp > other.cmp
    def __eq__(self, other):
        return self.cmp == other.cmp
    def __lt__(self, other):
        return self.cmp < other.cmp
        

foo = sorted([Itr(3), Itr(1), Itr(10), Itr(4)])
print [a.cmp for a in foo]
funktioniert soweit bei mir. K.A., ob dir das hilft ...
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@frabron:
Danke für Dein Beispiel! Ich hab' mir auch EyDu's Vorschlag mit operator.attrgetter angesehen und finde, dass eine Lösung damit einfacher und laut Doku auch schneller ist.
Zudem müsste ich mit Deiner Lösung das Sortierkriterium, das nicht immer gleich ist, im Exemplar festlegen was IMHO nicht so schön ist als selbiges 'von außen' zu bestimmen.

Gruß
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

EyDu und mich trennen wohl ca. Äonen an Programmiererfahrung :D

Ich wusste einfach nicht, ob mein Vorschlag mit den Vergleichsoperatoren auf dem Objekt funktioniert, deshalb hab ich ihn halt flott ausprobiert und das Resultat für die Nachwelt erhalten :) Nicht, dass ich es nicht geahnt hätte, aber man weiss ja nie :D
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@frabron: Du kannst sogar noch ein wenig vereinfachen:

Code: Alles auswählen

>>> class Spam(object):
...     def __init__(self, eggs):
...         self.eggs = eggs
...     def __cmp__(self, other):
...         return cmp(self.eggs, other.eggs)
...     def __repr__(self):
...         return "%s(%r)" % (self.__class__.__name__, self.eggs)
... 
>>> sorted([Spam(42), Spam(23), Spam(30), Spam(7)])
[Spam(7), Spam(23), Spam(30), Spam(42)]
Das Leben ist wie ein Tennisball.
Antworten