Nie całkiem rozumiem składnię sorted()
argumentu:
key=lambda variable: variable[0]
Czy nie jest lambda
arbitralne? Dlaczego jest variable
podane dwukrotnie w tym, co wygląda jak adict
?
Nie całkiem rozumiem składnię sorted()
argumentu:
key=lambda variable: variable[0]
Czy nie jest lambda
arbitralne? Dlaczego jest variable
podane dwukrotnie w tym, co wygląda jak adict
?
Odpowiedzi:
key
to funkcja, która zostanie wywołana w celu przekształcenia elementów kolekcji przed ich porównaniem. Parametr przekazany dokey
musi być wywoływalny.
Użycie lambda
tworzy anonimową funkcję (którą można wywołać). W przypadku sorted
wywoływanego przyjmuje tylko jeden parametr. Python lambda
jest dość prosty. Tak naprawdę może zrobić i zwrócić tylko jedną rzecz.
Składnia lambda
to słowo, lambda
po którym następuje lista nazw parametrów, a następnie pojedynczy blok kodu. Lista parametrów i blok kodu są oddzielone dwukropkiem. Jest to podobne do innych konstrukcji w Pythonie, jak również takich jak while
, for
, if
i tak dalej. Wszystkie są instrukcjami, które zazwyczaj zawierają blok kodu. Lambda to po prostu kolejny przykład instrukcji z blokiem kodu.
Możemy porównać użycie lambdy z def przy tworzeniu funkcji.
adder_lambda = lambda parameter1,parameter2: parameter1+parameter2
def adder_regular(parameter1, parameter2): return parameter1+parameter2
lambda po prostu daje nam sposób na zrobienie tego bez przypisywania nazwy. Co sprawia, że świetnie nadaje się do używania jako parametru funkcji.
variable
jest tu używany dwukrotnie, ponieważ po lewej stronie dwukropka jest to nazwa parametru, a po prawej jest używany w bloku kodu do obliczenia czegoś.
Myślę, że wszystkie odpowiedzi tutaj dość dobrze obejmują rdzeń funkcji lambda w kontekście sort (), jednak nadal czuję, że brakuje opisu prowadzącego do intuicyjnego zrozumienia, więc oto moje dwa centy.
Ze względu na kompletność podam z góry oczywiste: sortowane () zwraca listę posortowanych elementów i czy chcemy posortować w określony sposób lub jeśli chcemy posortować złożoną listę elementów (np. Listy zagnieżdżone lub lista krotek) możemy wywołać argument klucz.
Dla mnie intuicyjne zrozumienie kluczowego argumentu, dlaczego musi być wywoływalny, i użycie lambdy jako (anonimowej) funkcji wywoływalnej, aby to osiągnąć, składa się z dwóch części.
Składnia lambda jest następująca:
lambda input_variable (s) : smaczna jedna linijka
na przykład
In [1]: f00 = lambda x: x/2
In [2]: f00(10)
Out[2]: 5.0
In [3]: (lambda x: x/2)(10)
Out[3]: 5.0
In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0
In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
key
argumentu jest to, że powinien on przyjąć zestaw instrukcji, które zasadniczo będą wskazywać funkcję „sort ()” na te elementy listy, według których należy sortować. Kiedy mówi key=
, to naprawdę oznacza: Kiedy iteruję po liście po jednym elemencie na raz (tj. Dla e na liście), przekażę bieżący element do funkcji, którą podaję w kluczowym argumencie i użyję tego stworzyć przekształconą listę, która poinformuje mnie o kolejności ostatecznej posortowanej listy.Sprawdź to:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)
Przykład podstawowy:
sorted(mylist)
[2, 3, 3, 4, 6, 8, 23] # wszystkie liczby są w kolejności od małych do dużych.
Przykład 1:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)
[3, 3, 23, 6, 2, 4, 8] # Czy ten posortowany wynik ma dla Ciebie intuicyjny sens?
Zauważ, że moja funkcja lambda nakazała sortowanemu sprawdzić, czy (e) jest parzyste lub nieparzyste przed sortowaniem.
ALE POCZEKAJ! Możesz (a może powinieneś) zastanawiać się nad dwiema rzeczami - po pierwsze, dlaczego moje szanse są przed moimi wartościami parzystymi (ponieważ moja kluczowa wartość wydaje się wskazywać mojej funkcji sortowania, aby nadawała priorytet parzystym wartościom za pomocą operatora mod in x%2==0
). Po drugie, dlaczego moje liczby parzyste są niesprawne? 2 jest przed 6, prawda? Analizując ten wynik, dowiemy się czegoś głębszego o tym, jak działa argument „klucz” sortowany (), szczególnie w połączeniu z anonimową funkcją lambda.
Po pierwsze, zauważysz, że chociaż szanse są przed wydarzeniami parzystymi, same nieparzyste nie są sortowane. Dlaczego to?? Przeczytajmy dokumenty :
Funkcje klawiszy Począwszy od Pythona 2.4, zarówno list.sort (), jak i sortowane () dodały parametr key, aby określić funkcję, która ma być wywołana w każdym elemencie listy przed wykonaniem porównań.
Musimy trochę poczytać między wierszami, ale to nam mówi, że funkcja sort jest wywoływana tylko raz, a jeśli określimy argument klucz, to sortujemy według wartości, na którą wskazuje nam funkcja klucza.
Więc jaki jest przykład z użyciem zwrotu modulo? Wartość logiczna: True == 1
, False == 0
. Jak więc sort radzi sobie z tym kluczem? Zasadniczo przekształca oryginalną listę na sekwencję jedynek i zer.
[3,6,3,2,4,8,23] staje się [0,1,0,1,1,1,0]
Teraz dokądś zmierzamy. Co otrzymujesz, gdy posortujesz przekształconą listę?
[0,0,0,1,1,1,1]
Okej, więc teraz wiemy, dlaczego szanse są przed wydarzeniami. Ale następne pytanie brzmi: dlaczego 6 nadal występuje przed 2 na mojej ostatecznej liście? Cóż, to proste - to dlatego, że sortowanie odbywa się tylko raz! tj. te 1 nadal reprezentują oryginalne wartości listy, które znajdują się w swoich oryginalnych pozycjach względem siebie. Ponieważ sortowanie odbywa się tylko raz i nie wywołujemy żadnej funkcji sortowania, aby uporządkować oryginalne wartości parzyste od niskiego do wysokiego, wartości te pozostają w pierwotnej kolejności względem siebie.
Ostatnie pytanie brzmi zatem: Jak myślę koncepcyjnie o tym, jak kolejność moich wartości boolowskich zostanie przekształcona z powrotem do pierwotnych wartości, kiedy wydrukuję ostateczną posortowaną listę?
Sorted () to wbudowana metoda, która (fajny fakt) używa hybrydowego algorytmu sortowania o nazwie Timsortłączący w sobie aspekty sortowania przez scalanie i sortowanie przez wstawianie. Wydaje mi się jasne, że kiedy to nazywasz, istnieje mechanika, która utrzymuje te wartości w pamięci i łączy je z ich logiczną tożsamością (maską) określoną przez (...!) Funkcję lambda. Porządek jest określany przez ich tożsamość logiczną obliczoną z funkcji lambda, ale należy pamiętać, że te listy podrzędne (jedynek i zer) same nie są sortowane według ich oryginalnych wartości. W związku z tym ostateczna lista, chociaż jest zorganizowana według kursów i wartości parzystych, nie jest sortowana według podlisty (w tym przypadku nieparzyste są w kolejności). Fakt, że kursy są uporządkowane, wynika z tego, że przez przypadek były już uporządkowane na pierwotnej liście. Wniosek z tego wszystkiego jest taki, że kiedy lambda dokonuje tej transformacji, pierwotna kolejność podlist zostaje zachowana.
Jak więc to wszystko ma się do pierwotnego pytania, a co ważniejsze, do naszej intuicji, jak powinniśmy zaimplementować sort () z jej kluczowym argumentem i lambdą?
Tę funkcję lambda można traktować jako wskaźnik wskazujący na wartości, według których musimy posortować, niezależnie od tego, czy jest to wskaźnik odwzorowujący wartość na jej wartość logiczną przekształconą przez funkcję lambda, czy też jest to określony element zagnieżdżonej listy, krotki, dict itp., ponownie określane przez funkcję lambda.
Spróbujmy przewidzieć, co się stanie, gdy uruchomię następujący kod.
mylist = [(3, 5, 8), (6, 2, 8), ( 2, 9, 4), (6, 8, 5)]
sorted(mylist, key=lambda x: x[1])
Moje sorted
wezwanie mówi oczywiście: „Proszę posortować tę listę”. Kluczowy argument sprawia, że jest to trochę bardziej szczegółowe, mówiąc, że dla każdego elementu (x) w mylist należy zwrócić indeks 1 tego elementu, a następnie posortować wszystkie elementy oryginalnej listy „mylist” według posortowanej kolejności listy obliczonej przez funkcja lambda. Ponieważ mamy listę krotek, możemy zwrócić indeksowany element z tej krotki. Więc otrzymujemy:
[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]
Uruchom ten kod, a przekonasz się, że to jest kolejność. Spróbuj zindeksować listę liczb całkowitych, a zobaczysz, że kod się zepsuje.
To było rozwlekłe wyjaśnienie, ale mam nadzieję, że pomoże to „uporządkować” Twoją intuicję dotyczącą użycia funkcji lambda jako kluczowego argumentu w sort () i poza nią.
key
funkcji. Jeśli próbujesz zrozumieć sorted
funkcję, lambda
składnia po prostu przeszkadza w zrozumieniu.
lambda
to słowo kluczowe Pythona używane do generowania anonimowych funkcji .
>>> (lambda x: x+2)(3)
5
3
ponieważ są przekazywane do funkcji. Pareny znajdują się wokół lambdy, więc wyrażenie nie jest analizowane jako lambda x: x+2(3)
, co jest nieprawidłowe, ponieważ 2
nie jest funkcją.
Jeszcze jeden przykład użycia funkcji sortowanej () z kluczem = lambda. Rozważmy, że masz listę krotek. W każdej krotce masz markę, model i wagę samochodu i chcesz posortować tę listę krotek według marki, modelu lub wagi. Możesz to zrobić za pomocą lambdy.
cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]
print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))
Wyniki:
[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]
Ponieważ zapytano o użycie lambdy w kontekście sorted()
, spójrz na to również https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions
Aby przeformułować, klucz (Opcjonalnie. Funkcja do wykonania w celu ustalenia kolejności. Domyślnie jest to Brak) w posortowanych funkcjach oczekuje funkcji i używasz lambda.
Aby zdefiniować lambdę, określasz właściwość obiektu, którą chcesz sortować, a wbudowana funkcja sortowania Pythona automatycznie się tym zajmie.
Jeśli chcesz sortować według wielu właściwości, przypisz klucz = lambda x: (właściwość1, właściwość2).
Aby określić kolejność, podaj reverse = true jako trzeci argument (Opcjonalne. Wartość logiczna. False - sortowanie rosnąco, True - malejąco. Wartość domyślna to False) posortowanej funkcji.
Prosta i nie czasochłonna odpowiedź z przykładem adekwatnym do zadanego pytania Postępuj zgodnie z tym przykładem:
user = [{"name": "Dough", "age": 55},
{"name": "Ben", "age": 44},
{"name": "Citrus", "age": 33},
{"name": "Abdullah", "age":22},
]
print(sorted(user, key=lambda el: el["name"]))
print(sorted(user, key= lambda y: y["age"]))
Spójrz na nazwiska na liście, zaczynają się od D, B, C i A. A jeśli zauważysz wiek, są to 55, 44, 33 i 22. Pierwszy wydrukowany kod
print(sorted(user, key=lambda el: el["name"]))
Wyniki do:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Ben', 'age': 44},
{'name': 'Citrus', 'age': 33},
{'name': 'Dough', 'age': 55}]
sortuje nazwę, ponieważ przez klucz = lambda el: el ["nazwa"] sortujemy nazwy i nazwy zwracane w kolejności alfabetycznej.
Drugi kod wydruku
print(sorted(user, key= lambda y: y["age"]))
Wynik:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Citrus', 'age': 33},
{'name': 'Ben', 'age': 44},
{'name': 'Dough', 'age': 55}]
sortuje według wieku, a zatem lista jest zwracana rosnąco według wieku.
Wypróbuj ten kod, aby lepiej zrozumieć.
def
.