Mam listę słowników i chcę, aby każdy element był sortowany według określonych wartości właściwości.
Weź pod uwagę tablicę poniżej,
[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]
Po posortowaniu name
, powinien zostać
[{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]
[{'name':'Bart', 'age':10, 'note':3},{'name':'Homer','age':10,'note':2},{'name':'Vasile','age':20,'note':3}]
I do użycia:from operator import itemgetter newlist = sorted(old_list, key=itemgetter(-'note','name')
EDYCJA: Przetestowano i działa, ale nie wiem, jak zrobić notatkę DESC i nazwać ASC.Odpowiedzi:
Może wyglądać na czystsze za pomocą klucza zamiast cmp:
lub jak sugerowali JFSebastian i inni,
Dla kompletności (jak wskazano w komentarzach fitzgeraldsteele), dodaj
reverse=True
do sortowania malejącoźródło
itemgetter(i)
gdziei
jest indeks elementu krotki do sortowania.itemgetter
akceptuje więcej niż jeden argument:itemgetter(1,2,3)
jest funkcją, która zwraca krotkęobj[1], obj[2], obj[3]
, dzięki czemu można jej używać do wykonywania złożonych sortowań.Aby posortować listę słowników według klucza = „nazwa”:
Aby posortować listę słowników według klucza = „wiek”:
źródło
key=lambda k: (k['name'], k['age'])
. (lubkey=itemgetter('name', 'age')
). krotkicmp
porównują kolejno każdy element. to jest cholernie genialne.key
argument dlalist.sort()
nie jest opisany. Masz pomysł, gdzie to znaleźć?list
znajomych i przyjaciół.my_list
będzie teraz tym, czego chcesz.(3 lata później) Edytowano, aby dodać:
Nowy
key
argument jest bardziej wydajny i bardziej przejrzysty. Lepsza odpowiedź wygląda teraz:... lambda jest, IMO, łatwiejsze do zrozumienia niż
operator.itemgetter
, ale YMMV.źródło
Jeśli chcesz posortować listę według wielu kluczy, możesz wykonać następujące czynności:
Jest to dość hackerskie, ponieważ polega na przekształceniu wartości w reprezentację pojedynczego ciągu w celu porównania, ale działa zgodnie z oczekiwaniami w przypadku liczb, w tym ujemnych (chociaż będziesz musiał odpowiednio sformatować swój ciąg zerami, jeśli używasz liczb)
źródło
„klucz” służy do sortowania według dowolnej wartości, a „itemgetter” ustawia tę wartość do atrybutu „name” każdego elementu.
źródło
źródło
Chyba miałeś na myśli:
To byłoby posortowane w następujący sposób:
źródło
Możesz użyć niestandardowej funkcji porównania lub przekazać funkcję, która oblicza niestandardowy klucz sortowania. Zwykle jest to bardziej wydajne, ponieważ klucz jest obliczany tylko raz na pozycję, podczas gdy funkcja porównania byłaby wywoływana wiele razy.
Możesz to zrobić w ten sposób:
Ale średnia biblioteka zawiera ogólną procedurę dla coraz elementy dowolnych obiektów:
itemgetter
. Spróbuj więc zamiast tego:źródło
Używając transformacji Schwartzian z Perla,
zrobić
daje
Więcej na temat transformacji Perla Schwartziana
źródło
key=
na.sort
od 2,4, to jest rok 2004, to robi Transformacja Schwartza w kodzie sortowania w C; dlatego ta metoda jest przydatna tylko w Pythons 2.0-2.3. z których wszystkie mają więcej niż 12 lat.Musisz wdrożyć własną funkcję porównywania, która będzie porównywać słowniki według wartości kluczy nazw. Zobacz temat Sortowanie mini-JAK Z PythonInfo Wiki
źródło
czasami musimy
lower()
na przykład użyćźródło
Oto alternatywne rozwiązanie ogólne - sortuje elementy dict według kluczy i wartości. Zaletą tego jest to, że nie trzeba określać kluczy, a nadal działałoby, gdyby niektórych kluczy brakowało w niektórych słownikach.
źródło
Korzystanie z pakietu pand to kolejna metoda, choć jego środowisko uruchomieniowe na dużą skalę jest znacznie wolniejsze niż bardziej tradycyjne metody proponowane przez innych:
Oto kilka wartości porównawczych dla małej listy i dużej (100 tys.) Listy nagrań:
źródło
Jeśli nie trzeba oryginał
list
zdictionaries
, można zmodyfikować go w miejscu zsort()
metodą z użyciem funkcji klawisza zwyczaj.Klawisz funkcyjny:
Do
list
posortowania:Sortowanie w miejscu:
Jeśli potrzebujesz oryginału
list
, wywołajsorted()
funkcję przekazującą golist
i funkcję klucza, a następnie przypisz zwrócony sortlist
do nowej zmiennej:Drukowanie
data_one
inew_data
.źródło
Powiedzmy, że mam słownik
D
z elementami poniżej. Aby posortować, użyj posortowanego argumentu w celu przekazania funkcji niestandardowej, jak poniżej:Sprawdź to .
źródło
Byłem wielkim fanem filtra w / lambda, jednak nie jest to najlepsza opcja, jeśli wziąć pod uwagę złożoność czasu
Pierwsza opcja
Druga opcja
Szybkie porównanie czasów wykonania
źródło
Jeśli problemem jest wydajność, użyłbym
operator.itemgetter
zamiast tego,lambda
ponieważ wbudowane funkcje działają szybciej niż funkcje ręcznie wykonane.itemgetter
Funkcja wydaje się wykonać około 20% szybciej niżlambda
w oparciu o moje badania.Od https://wiki.python.org/moin/PythonSpeed :
Oto porównanie prędkości sortowania używając
lambda
vsitemgetter
.Obie techniki sortują listę w tej samej kolejności (weryfikowana przez wykonanie instrukcji końcowej w bloku kodu), ale jedna jest nieco szybsza.
źródło
Możesz użyć następującego kodu
źródło