Mam listę obiektów Python, które chciałbym posortować według atrybutu samych obiektów. Lista wygląda następująco:
>>> ut
[<Tag: 128>, <Tag: 2008>, <Tag: <>, <Tag: actionscript>, <Tag: addresses>,
<Tag: aes>, <Tag: ajax> ...]
Każdy obiekt ma liczbę:
>>> ut[1].count
1L
Muszę posortować listę według liczby malejących.
Widziałem kilka metod, ale szukam najlepszych praktyk w Pythonie.
Odpowiedzi:
Więcej informacji na temat sortowania według kluczy .
źródło
Najlepszym sposobem, który może być najszybszy, szczególnie jeśli twoja lista zawiera wiele rekordów, jest użycie
operator.attrgetter("count")
. Może to jednak działać na wcześniejszej wersji Pythona, więc dobrze byłoby mieć mechanizm awaryjny. Następnie możesz wykonać następujące czynności:źródło
self.__dict__ = {'some':'dict'}
po__init__
metodzie). Nie wiem jednak, dlaczego miałoby być inaczej.__dict__
. Zauważ, że „obiekt z dynamicznie dodawanymi atrybutami” i „ustawienie__dict__
atrybutu obiektu ” są prawie ortogonalnymi pojęciami. Mówię to, ponieważ twój komentarz wydaje się sugerować, że ustawienie__dict__
atrybutu jest warunkiem dynamicznego dodawania atrybutów.operator.attrgetter
, mógłbym podać funkcję o dowolnej nazwie właściwości i zwrócić posortowaną kolekcję.Czytelnicy powinni zauważyć, że metoda key =:
jest wiele razy szybsza niż dodawanie do obiektów bogatych operatorów porównania. Byłem zaskoczony, gdy to przeczytałem (str. 485 „Python w pigułce”). Możesz to potwierdzić, uruchamiając testy w tym małym programie:
Moje, bardzo minimalne testy pokazują, że pierwsze sortowanie jest ponad 10 razy wolniejsze, ale książka mówi, że ogólnie jest tylko około 5 razy wolniejsze. Mówią, że powodem jest wysoce zoptymalizowany algorytm sortowania używany w pythonie ( timsort ).
Jednak bardzo dziwne jest to, że .sort (lambda) jest szybszy niż zwykły stary .sort (). Mam nadzieję, że to naprawią.
źródło
__cmp__
jest równoznaczne z dzwonieniem.sort(cmp=lambda)
,.sort(key=lambda)
więc nie jest wcale dziwne.longList2.sort(cmp = cmp)
. Wypróbowałem to i działało prawie tak samo jak.sort()
. (Również: zauważ, że parametr sortowania „cmp” został usunięty w Pythonie 3.)Podejście obiektowe
Dobrą praktyką jest, aby logika sortowania obiektów, jeśli ma zastosowanie, była właściwością klasy, a nie włączana w każdym przypadku, w którym wymagane jest porządkowanie.
Zapewnia to spójność i eliminuje potrzebę stosowania kodu płyty kotłowej.
Co najmniej należy określić
__eq__
i__lt__
działania, aby to zadziałało. Więc po prostu użyjsorted(list_of_objects)
.źródło
__eq__
i jakie__lt__
są minimalne wymagania dotyczące wdrażania?•The sort routines are guaranteed to use __lt__() when making comparisons between two objects...
źródło
Wygląda bardzo podobnie do listy instancji modelu Django ORM.
Dlaczego nie posortować ich według zapytania:
źródło
Dodaj operatory porównania bogatego do klasy obiektowej, a następnie użyj metody sort () z listy.
Zobacz bogate porównanie w pythonie .
Aktualizacja : Chociaż ta metoda zadziałałaby, myślę, że rozwiązanie z Tryptyku lepiej pasuje do twojego przypadku, ponieważ jest prostsze.
źródło
Jeśli atrybut, który chcesz posortować, jest właściwością , możesz uniknąć importowania
operator.attrgetter
ifget
zamiast tego użyć metody właściwości .Na przykład dla klasy
Circle
z właściwościąradius
możemy posortować listęcircles
według promieni w następujący sposób:To nie jest najbardziej znana funkcja, ale często zapisuje mi linię przy imporcie.
źródło