Sortieren, wie für diejenigen, die nach weiteren Informationen zum Sortieren in Python suchen.
– Jeyekomon
30. Mai 2018 um 8:48 Uhr
abgesehen von operator.attrgetter(‘attribute_name’) können Sie auch Funktoren als Schlüssel wie object_list.sort(key=my_sorting_functor(‘my_key’) verwenden und die Implementierung bewusst weglassen.
– Vijay Shanker
8. April 2019 um 20:07 Uhr
Kenan-Banken
# To sort the list in place...
ut.sort(key=lambda x: x.count, reverse=True)
# To return a new list, use the sorted() built-in function...
newlist = sorted(ut, key=lambda x: x.count, reverse=True)
Kein Problem. Übrigens, wenn muhuk Recht hat und es sich um eine Liste von Django-Objekten handelt, sollten Sie seine Lösung in Betracht ziehen. Für den allgemeinen Fall des Sortierens von Objekten ist meine Lösung jedoch wahrscheinlich die beste Vorgehensweise.
– Kenan-Banken
31. Dezember 2008 um 17:12 Uhr
Bei großen Listen erhalten Sie eine bessere Leistung, wenn Sie operator.attrgetter(‘count’) als Schlüssel verwenden. Dies ist nur eine optimierte (untere) Form der Lambda-Funktion in dieser Antwort.
– David Eik
31. Dezember 2008 um 19:35 Uhr
Danke für die tolle Antwort. Falls es sich um eine Liste von Wörterbüchern handelt und „count“ einer ihrer Schlüssel ist, muss sie wie folgt geändert werden: ut.sort(key=lambda x: x[‘count’]umgekehrt = wahr)
– dganesh2002
8. Dezember 2016 um 21:20 Uhr
Ich nehme an, es verdient das folgende Update: Wenn nach mehreren Feldern sortiert werden muss, kann dies durch aufeinanderfolgende Aufrufe von sort() erreicht werden, da Python einen stabilen Sortieralgorithmus verwendet.
– uuu777
23. Februar 2020 um 14:41 Uhr
Danke @KenanBanks, du hattest Recht. Ärgerlicherweise machte Outlook einige seltsame Dinge mit Kalenderzeitzonen, so dass einige ohne die Zeitzonendetails durchkamen … keine Ahnung warum!
– Schmied
20. April 2022 um 6:05 Uhr
tzot
Eine Möglichkeit, die am schnellsten sein kann, insbesondere wenn Ihre Liste viele Datensätze enthält, ist die Verwendung operator.attrgetter("count"). Dies könnte jedoch auf einer Pre-Operator-Version von Python ausgeführt werden, daher wäre es schön, einen Fallback-Mechanismus zu haben. Vielleicht möchten Sie dann Folgendes tun:
try: import operator
except ImportError: keyfun= lambda x: x.count # use a lambda if no operator module
else: keyfun= operator.attrgetter("count") # use operator since it's faster than lambda
ut.sort(key=keyfun, reverse=True) # sort in-place
Hier würde ich den Variablennamen „keyfun“ anstelle von „cmpfun“ verwenden, um Verwirrung zu vermeiden. Die Methode sort() akzeptiert auch eine Vergleichsfunktion über das Argument cmp=.
– akaihola
2. Januar 2009 um 12:16 Uhr
Dies scheint nicht zu funktionieren, wenn das Objekt dynamisch hinzugefügte Attribute hat (falls Sie dies getan haben self.__dict__ = {'some':'dict'} nach dem __init__ Methode). Ich wüsste aber nicht, warum es anders sein sollte.
– tutuca
7. Januar 2013 um 20:40 Uhr
@tutuca: Ich habe die Instanz nie ersetzt __dict__. Beachten Sie, dass „ein Objekt mit dynamisch hinzugefügten Attributen“ und „ein Objekt festlegen __dict__ Attribut” sind fast orthogonale Konzepte. Ich sage das, weil Ihr Kommentar zu implizieren scheint, dass die Einstellung der __dict__ Das Attribut ist eine Voraussetzung für das dynamische Hinzufügen von Attributen.
– zot
9. Januar 2013 um 23:14 Uhr
@tzot: Wenn ich die Verwendung von verstehe operator.attrgetterkönnte ich eine Funktion mit einem beliebigen Eigenschaftsnamen bereitstellen und eine sortierte Sammlung zurückgeben.
ist um ein Vielfaches schneller als das Hinzufügen umfangreicher Vergleichsoperatoren zu den Objekten. Ich war überrascht, dies zu lesen (Seite 485 von „Python in a Nutshell“). Sie können dies bestätigen, indem Sie Tests mit diesem kleinen Programm ausführen:
#!/usr/bin/env python
import random
class C:
def __init__(self,count):
self.count = count
def __cmp__(self,other):
return cmp(self.count,other.count)
longList = [C(random.random()) for i in xrange(1000000)] #about 6.1 secs
longList2 = longList[:]
longList.sort() #about 52 - 6.1 = 46 secs
longList2.sort(key = lambda c: c.count) #about 9 - 6.1 = 3 secs
Meine sehr minimalen Tests zeigen, dass die erste Sorte mehr als 10-mal langsamer ist, aber das Buch sagt, dass sie im Allgemeinen nur etwa 5-mal langsamer ist. Der Grund, den sie sagen, ist auf den hochoptimierten Sortieralgorithmus zurückzuführen, der in Python verwendet wird (Zeitsort).
Trotzdem ist es sehr seltsam, dass .sort(lambda) schneller ist als das einfache alte .sort(). Ich hoffe, sie beheben das.
Definieren __cmp__ ist gleichbedeutend mit anrufen .sort(cmp=lambda)nicht .sort(key=lambda)also ist es überhaupt nicht seltsam.
– zot
9. September 2019 um 7:46 Uhr
@tzot ist genau richtig. Die erste Sorte muss immer wieder Gegenstände miteinander vergleichen. Die zweite Sortierung greift nur einmal auf jedes Objekt zu, um seinen Zählwert zu extrahieren, und führt dann eine einfache numerische Sortierung durch, die hochoptimiert ist. Ein fairer Vergleich wäre longList2.sort(cmp = cmp). Ich habe das ausprobiert und es hat fast die gleiche Leistung erbracht wie .sort(). (Außerdem: Beachten Sie, dass der Sortierparameter „cmp“ in Python 3 entfernt wurde.)
Es empfiehlt sich, die Objektsortierlogik, falls zutreffend, zu einer Eigenschaft der Klasse zu machen, anstatt sie in jeder Instanz zu integrieren, in der die Reihenfolge erforderlich ist.
Dies gewährleistet Konsistenz und macht Boilerplate-Code überflüssig.
Sie sollten mindestens angeben __eq__ Und __lt__ Operationen, damit dies funktioniert. Dann einfach verwenden sorted(list_of_objects).
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __eq__(self, other):
return self.rank == other.rank and self.suit == other.suit
def __lt__(self, other):
return self.rank < other.rank
hand = [Card(10, 'H'), Card(2, 'h'), Card(12, 'h'), Card(13, 'h'), Card(14, 'h')]
hand_order = [c.rank for c in hand] # [10, 2, 12, 13, 14]
hand_sorted = sorted(hand)
hand_sorted_order = [c.rank for c in hand_sorted] # [2, 10, 12, 13, 14]
from operator import attrgetter
ut.sort(key = attrgetter('count'), reverse = True)
Muhuk
Es sieht aus wie eine Liste von Django-ORM-Modellinstanzen.
Warum sortieren Sie sie nicht nach Abfrage wie folgt:
ut = Tag.objects.order_by('-count')
rauben
Fügen Sie der Objektklasse umfangreiche Vergleichsoperatoren hinzu und verwenden Sie dann die Methode sort() der Liste.
Sehen reichhaltiger Vergleich in Python.
Aktualisieren: Obwohl diese Methode funktionieren würde, denke ich, dass die Lösung von Triptych für Ihren Fall besser geeignet ist, weil sie viel einfacher ist.
14435000cookie-checkWie sortiere ich eine Liste von Objekten basierend auf einem Attribut der Objekte in absteigender Reihenfolge?yes
Dupe: stackoverflow.com/questions/157424/…, stackoverflow.com/questions/222752/…, stackoverflow.com/questions/327191/…
– S. Lott
31. Dezember 2008 um 18:23 Uhr
Sortieren, wie für diejenigen, die nach weiteren Informationen zum Sortieren in Python suchen.
– Jeyekomon
30. Mai 2018 um 8:48 Uhr
abgesehen von operator.attrgetter(‘attribute_name’) können Sie auch Funktoren als Schlüssel wie object_list.sort(key=my_sorting_functor(‘my_key’) verwenden und die Implementierung bewusst weglassen.
– Vijay Shanker
8. April 2019 um 20:07 Uhr