Jestem nowicjuszem w Pythonie próbującym osiągnąć następujące cele:
Mam listę list:
lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]
Chcę mapować lst na inną listę zawierającą tylko drugą najmniejszą liczbę z każdej podlisty. Więc wynik powinien być:
[345, 465, 333]
Na przykład, gdybym był zainteresowany najmniejszą liczbą, mógłbym zrobić:
map(lambda x: min(x),lst)
Chciałbym móc to zrobić:
map(lambda x: sort(x)[1],lst)
ale sortowanie nie tworzy łańcucha. (zwraca Brak)
też coś takiego nie jest dozwolone:
map(lambda x: sort(x); x[1],lst) #hence the multiple statement question
Czy istnieje sposób na zrobienie tego z mapą w Pythonie, ale bez definiowania nazwanej funkcji ? (jest to łatwe, na przykład z anonimowymi blokami w rubinie)
lambda x: sort(x) OR x[1]
zadziała: tutaj OR oblicza swój pierwszy argument (zwracana wartość None) jako bool (=> False), a w tym przypadku OR zwraca swój drugi argument. Ale jak mówią odpowiedzi, lepiej unikać lambda.Odpowiedzi:
Mogę tu udzielić kilku różnych odpowiedzi, od konkretnego pytania po bardziej ogólne wątpliwości. A więc od najbardziej szczegółowych do najbardziej ogólnych:
P. Czy możesz umieścić wiele instrukcji w lambdzie?
O. Nie. Ale tak naprawdę nie musisz używać lambdy. Zamiast tego możesz umieścić instrukcje w
def
. to znaczy:P. Czy możesz uzyskać drugą najniższą pozycję z lambda, sortując listę?
A. Tak. Jak wskazuje odpowiedź Alexa,
sorted()
jest to wersja, która tworzy nową listę zamiast sortowania na miejscu i może być połączona łańcuchowo. Zauważ, że prawdopodobnie tego powinieneś używać - to zła praktyka, jeśli twoja mapa ma efekty uboczne na oryginalnej liście.P. Jak mogę uzyskać drugą najniższą pozycję z każdej listy w sekwencji list?
A.
sorted(l)[1]
nie jest do tego najlepszym sposobem. Ma złożoność O (N log (N)), podczas gdy istnieje rozwiązanie O (n). Można to znaleźć w module heapq.Więc po prostu użyj:
Zwykle uważa się również, że jaśniejsze jest użycie rozumienia list, które całkowicie pozwala uniknąć lambdy:
źródło
k
(jak tutaj z „drugą najniższą”)O(k*log(n)+n)
upraszcza doO(n)
Umieszczenie wyciągów na liście może symulować wiele instrukcji:
Na przykład:
źródło
None
.Podróżnik w czasie tutaj. Jeśli generalnie chcesz mieć wiele instrukcji w lambdzie, możesz przekazać inne lambdy jako argumenty do tej lambdy.
W rzeczywistości nie możesz mieć wielu instrukcji, ale możesz to zasymulować, przekazując lambdy do lambd.
Edycja: podróżnik w czasie powraca! Możesz także nadużywać zachowania wyrażeń boolowskich (pamiętając o krótkich regułach i prawdziwości) w operacjach łańcuchowych. Korzystanie z operatora trójskładnikowego zapewnia jeszcze większą moc. Ponownie, nie możesz mieć wielu instrukcji , ale możesz oczywiście mieć wiele wywołań funkcji. Ten przykład zawiera jakieś przypadkowe śmieci z dużą ilością danych, ale pokazuje, że możesz zrobić kilka zabawnych rzeczy. Instrukcje print są przykładami funkcji, które zwracają
None
(podobnie jak.sort()
metoda), ale pomagają też pokazać, colambda
robi.źródło
Użyj posortowanej funkcji , takiej jak ta:
źródło
[sorted(x)[1] for x in list_of_lists]
.W rzeczywistości możesz mieć wiele instrukcji w wyrażeniu lambda w Pythonie. Nie jest to całkowicie trywialne, ale w twoim przykładzie działa to:
Musisz się upewnić, że każda instrukcja nic nie zwraca lub zawija ją w (.. i False). Wynik jest tym, co jest zwracane przez ostatnią ocenę.
Przykład:
źródło
Korzystanie z funkcji begin () tutaj: http://www.reddit.com/r/Python/comments/hms4z/ask_pyreddit_if_you_were_making_your_own/c1wycci
źródło
Hackim sposobem łączenia wielu instrukcji w jedną instrukcję w Pythonie jest użycie słowa kluczowego „and” jako operatora zwarcia. Następnie możesz użyć tej pojedynczej instrukcji bezpośrednio jako części wyrażenia lambda.
Jest to podobne do używania „&&” jako operatora zwarcia w językach powłoki, takich jak bash.
Uwaga: zawsze można naprawić instrukcję funkcji, aby zwracała wartość true, opakowując funkcję.
Przykład:
Po drugie, prawdopodobnie lepiej jest użyć znaku „lub” zamiast „i”, ponieważ wiele funkcji po pomyślnym zakończeniu zwraca „0” lub „Brak”. Następnie możesz pozbyć się funkcji opakowującej z powyższego przykładu:
Operacje „and” będą oceniać wyrażenia, aż dojdą do pierwszej zwracanej wartości zerowej. po czym zwiera. 1 i 1 oraz 0 i 1 oceniają: 1 i 1 i 0, a spadają 1
Operacja 'or' będzie oceniać wyrażenia, aż dojdzie do pierwszej niezerowej wartości zwracanej. po czym zwiera.
0 lub 0 lub 1 lub 0 daje 0 lub 0 lub 1 i spada 0
źródło
Lub jeśli chcesz uniknąć lambdy i mieć generator zamiast listy:
(posortowane (kol) [1] dla kolumny w lst)
źródło
Pozwólcie, że przedstawię wam wspaniały, ale przerażający hack:
Możesz teraz użyć tego
LET
formularza jako takiego:co daje:
[345, 465, 333]
źródło
Możesz to zrobić w czasie O (n), używając min i index zamiast sortowania lub heapq.
Najpierw utwórz nową listę wszystkiego poza minimalną wartością oryginalnej listy:
Następnie weź minimalną wartość nowej listy:
Teraz wszystko razem w jednej lambdzie:
Tak, jest naprawdę brzydki, ale algorytmicznie powinien być tani. Również ponieważ niektórzy ludzie w tym wątku chcą zobaczyć listy składane:
źródło
Dokładnie do tego
bind
służy funkcja w monadzie .Za pomocą tej
bind
funkcji można połączyć wiele lambda w jedną lambdę, z których każda reprezentuje instrukcję.źródło
W rzeczywistości istnieje sposób, w jaki można używać wielu instrukcji w lambdzie. Oto moje rozwiązanie:
źródło
exec
nie może być poddany introspekcji przez inteligentne IDETak. Możesz to zdefiniować w ten sposób, a następnie opakować swoje wyrażenia w następujący sposób:
Schemat zaczyna się:
begin = lambda * x: x [-1]
Wspólna prognoza Lisp:
progn = lambda * x: x [-1]
źródło
Są lepsze rozwiązania bez użycia funkcji lambda. Ale jeśli naprawdę chcemy użyć funkcji lambda, oto ogólne rozwiązanie do radzenia sobie z wieloma instrukcjami: map (lambda x: x [1] if (x.sort ()) else x [1], lst)
Nie obchodzi cię, co zwraca oświadczenie.
źródło
Tak to mozliwe. Wypróbuj poniższy fragment kodu.
źródło
Dam ci inne rozwiązanie, spraw, aby twoja lambda wywoływała funkcję.
źródło
junky = multiple_statements
.