Mam listę list:
[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
Gdybym chciał posortować według jednego elementu, powiedzmy wysoki / krótki element, mógłbym to zrobić za pośrednictwem s = sorted(s, key = itemgetter(1))
.
Gdybym chciał, aby posortować według zarówno wysoki / krótki i koloru, co mogłem zrobić to rodzaj dwa razy, raz dla każdego elementu, ale jest jakiś szybszy sposób?
sort
. Oznacza to, żesorted([(4, 2), (0, 3), (0, 1)]) == [(0, 1), (0, 3), (4, 2)]
.Odpowiedzi:
Klawisz może być funkcją zwracającą krotkę:
Lub możesz osiągnąć to samo, używając
itemgetter
(co jest szybsze i pozwala uniknąć wywołania funkcji Python):I zauważ, że tutaj możesz użyć
sort
zamiast używać,sorted
a następnie ponownie przypisywać:źródło
-
liczb całkowitych)revrse=True
tylko,x[1]
czy to możliwe?s = sorted(s, key = operator.itemgetter(2))
a następnie według pierwotnegos = sorted(s, key = operator.itemgetter(1), reverse=True)
Nie idealny, ale działa.-1
.Nie jestem pewien, czy jest to metoda najbardziej pythońska ... Miałem listę krotek, które wymagały sortowania 1. poprzez zejście liczb całkowitych i 2. alfabetycznie. Wymagało to odwrócenia sortowania według liczb całkowitych, ale nie sortowania alfabetycznego. Oto moje rozwiązanie: (w locie podczas egzaminu btw nawet nie wiedziałem, że można „zagnieżdżać” posortowane funkcje)
źródło
b = sorted(a, key = lambda x: (-x[1], x[0]))
było lepiej widoczne, które kryteria mają zastosowanie jako pierwsze. co do wydajności, nie jestem pewien, ktoś potrzebuje czasu.Wygląda na to, że możesz użyć
list
zamiast zamiasttuple
. Myślę, że staje się to ważniejsze, gdy chwytasz atrybuty zamiast „magicznych indeksów” listy / krotki.W moim przypadku chciałem posortować według wielu atrybutów klasy, gdzie przychodzące klucze były łańcuchami. Potrzebowałem innego sortowania w różnych miejscach i chciałem wspólnego domyślnego sortowania dla klasy nadrzędnej, z którą współpracowali klienci; tylko nadpisywanie „kluczy sortujących”, kiedy naprawdę „muszę”, ale także w taki sposób, że mógłbym przechowywać je jako listy, które klasa mogłaby udostępnić
Najpierw zdefiniowałem metodę pomocniczą
następnie go użyć
Spowoduje to użycie wygenerowanej funkcji lambda do sortowania listy,
object.attrA
a następnieobject.attrB
przy założeniu, żeobject
ma getter odpowiadający podanym nazwom ciągów. A druga sprawa będzie sortować wedługobject.attrC
potemobject.attrA
.Pozwala to również potencjalnie ujawnić opcje sortowania na zewnątrz, które mogą być udostępniane przez konsumenta, test jednostkowy, lub może powiedzieć im, w jaki sposób chcą sortowania dla niektórych operacji w interfejsie API, wystarczy podać listę, a nie łącząc je z implementacją zaplecza.
źródło
Kilka lat późno do partii, ale chcę zarówno sortowania na 2 kryteriach i użytkowania
reverse=True
. Jeśli ktoś chce wiedzieć, jak to zrobić, możesz zawrzeć kryteria (funkcje) w nawiasach:źródło
Oto jeden sposób: Zasadniczo ponownie piszesz swoją funkcję sortowania, aby pobrać listę funkcji sortowania, każda funkcja sortowania porównuje atrybuty, które chcesz przetestować, w każdym teście sortowania patrzysz i sprawdzasz, czy funkcja cmp zwraca niezerowy zwrot jeśli tak, przerwij i wyślij wartość zwrotną. Wywołujecie to, wywołując Lambda funkcji listy Lambdas.
Jego zaletą jest to, że przesyła dane pojedynczo, a nie jak poprzednie sortowanie, jak robią to inne metody. Kolejną rzeczą jest to, że sortuje się w miejscu, podczas gdy sortowanie wydaje się robić kopię.
Użyłem go do napisania funkcji rankingu, która uszeregowuje listę klas, w których każdy obiekt jest w grupie i ma funkcję punktacji, ale możesz dodać dowolną listę atrybutów. Zwróć uwagę na nie-lambda, choć hackerskie użycie lambda do wezwania setera. Część rangowa nie będzie działać dla szeregu list, ale sortowanie będzie.
Oto sposób na uszeregowanie listy obiektów
źródło