Mam następującą listę utworzoną z posortowanego pliku csv
list1 = sorted(csv1, key=operator.itemgetter(1))
Chciałbym właściwie posortować listę według dwóch kryteriów: najpierw według wartości w polu 1, a następnie według wartości w polu 2. Jak to zrobić?
__lt__()
metodę w swojej klasie lub dziedzicz z jakiejś klasy, która to robi” ? To uczyniłoby go znacznie lepszym kanonicznym.Odpowiedzi:
lubię to:
źródło
operator
to moduł, który należy zaimportować.Nie ma potrzeby importowania niczego podczas korzystania z funkcji lambda.
Poniższe sortuje
list
według pierwszego elementu, a następnie według drugiego elementu.źródło
-
w-x[1]
skrót?Python ma stabilne sortowanie, więc jeśli wydajność nie jest problemem, najprostszym sposobem jest posortowanie go według pola 2, a następnie sortowanie ponownie według pola 1.
To da ci pożądany wynik, jedyny haczyk polega na tym, że jeśli jest to duża lista (lub chcesz ją często sortować) dwukrotne wywołanie sort może być niedopuszczalnym narzutem.
Zrobienie tego w ten sposób ułatwia również obsługę sytuacji, w której chcesz, aby niektóre kolumny były sortowane odwrotnie, po prostu dołącz parametr „reverse = True”, gdy jest to konieczne.
W przeciwnym razie możesz przekazać wiele parametrów do itemgetter lub ręcznie utworzyć krotkę. Prawdopodobnie będzie to szybsze, ale problem polega na tym, że nie uogólnia się dobrze, jeśli niektóre kolumny chcą być sortowane odwrotnie (kolumny numeryczne nadal można odwrócić, negując je, ale to zatrzymuje sortowanie).
Więc jeśli nie potrzebujesz żadnych kolumn posortowanych odwrotnie, przejdź do wielu argumentów do itemgetter, jeśli możesz, a kolumny nie są numeryczne lub chcesz, aby sortowanie było stabilne dla wielu kolejnych sortowań.
Edycja: dla komentujących, którzy mają problemy ze zrozumieniem, w jaki sposób odpowiada to pierwotnemu pytaniu, oto przykład, który dokładnie pokazuje, w jaki sposób stabilny charakter sortowania zapewnia, że możemy wykonać oddzielne sortowanie dla każdego klucza i skończyć z danymi posortowanymi według wielu kryteriów:
To jest przykład, który można uruchomić, ale aby uratować ludzi, którzy go uruchamiają, otrzymujemy:
Zwróć uwagę w szczególności, jak w drugim kroku
reverse=True
parametr utrzymuje pierwsze nazwiska w kolejności, podczas gdy zwykłe sortowanie, a następnie odwracanie listy spowoduje utratę żądanej kolejności dla trzeciego klucza sortowania.źródło
źródło
tuple()
mogę otrzymać dwóch argumentów (a raczej trzech, jeśli liczyćself
)return
powinno byćreturn tuple((x[1], x[2]))
lub po prostureturn x[1], x[2]
. Skorzystaj z odpowiedzi @jaap poniżej, jeśli szukasz sortowania w różnych kierunkachtuple(x[1:3])
, jeśli z jakiegoś powodu chcesz użyć konstruktora krotki zamiast tylko listy wyświetlania krotkix[1], x[2]
. Lubkeyfunc = operator.itemgetter(1, 2)
i nawet nie pisz funkcji samodzielnie.Możemy również użyć .sort z lambda 2 razy, ponieważ sortowanie w Pythonie jest na miejscu i stabilne. Spowoduje to najpierw posortowanie listy według drugiego elementu, x [1]. Następnie posortuje pierwszy element, x [0] (najwyższy priorytet).
Jest to równoważne wykonaniu następujących czynności: workers.sort (key = lambda x: (x [0], x [1]))
źródło
W porządku rosnącym możesz użyć:
lub malejąco możesz użyć:
źródło
Sortowanie listy dykt za pomocą poniższego posortuje listę w porządku malejącym w pierwszej kolumnie jako wynagrodzenie, a w drugiej jako wiek
Wynik: [{'salary': 123, 'age': 25}, {'salary': 123, 'age': 23}]
źródło