Słyszałem, że w Pythonie nie można dodawać wielowierszowych lambd, ponieważ kolidują one składniowo z innymi konstrukcjami składni w Pythonie. Myślałem o tym dzisiaj w autobusie i zdałem sobie sprawę, że nie mogę wymyślić żadnego konstruktu w języku Python, z którym kolidują wielowierszowe lambdy. Biorąc pod uwagę, że znam język dość dobrze, to mnie zaskoczyło.
Teraz jestem pewien, że Guido miał powód, by nie uwzględniać wielowierszowych lambd w języku, ale z ciekawości: w jakiej sytuacji uwzględnienie wielowierszowej lambdy byłoby niejednoznaczne? Czy to, co słyszałem, jest prawdą, czy jest jakiś inny powód, dla którego Python nie zezwala na wieloliniowe lambdy?
lambda
przede wszystkim wyrażeń; możesz po prostu użyćdef
wyrażeń.Odpowiedzi:
Spójrz na następujące:
Czy to zwraca lambda
(y, [1,2,3])
(dlatego mapa otrzymuje tylko jeden parametr, co powoduje błąd)? Czy to zwracay
? Czy jest to błąd składniowy, ponieważ przecinek w nowym wierszu jest nieprawidłowo umieszczony? Skąd Python wiedziałby, czego chcesz?W obrębie parens wcięcie nie ma znaczenia dla Pythona, więc nie można jednoznacznie pracować z multiliniami.
To jest po prostu prosty, prawdopodobnie jest więcej przykładów.
źródło
Guido van Rossum (wynalazca Pythona) sam odpowiada na dokładnie to pytanie w starym poście na blogu .
Zasadniczo przyznaje, że jest to teoretycznie możliwe, ale każde proponowane rozwiązanie nie byłoby Pythonic:
źródło
Jest to na ogół bardzo brzydkie (ale czasami alternatywy są jeszcze bardziej brzydkie), więc obejście polega na utworzeniu wyrażenia nawiasów klamrowych:
Nie przyjmie jednak żadnych zadań, więc musisz wcześniej przygotować dane. Miejsce, które uznałem za przydatne, to opakowanie PySide, w którym czasami masz krótkie oddzwanianie. Pisanie dodatkowych funkcji składowych byłoby jeszcze bardziej brzydkie. Zwykle nie będziesz tego potrzebować.
Przykład:
źródło
lambda arg
isetattr(arg, 'attr','value')
obalenie „żadnych zadań ...”. A potem jest ocena zwarciaand
ior
... robi to JavaScript. Wrzuca w ciebie korzenie, jak bluszcz w ścianę. Mam prawie nadzieję, że zapomnę o tym w Boże Narodzenie.PEP
wytycznymi)Kilka odpowiednich linków:
Przez jakiś czas śledziłem rozwój Reii, która początkowo miała mieć składnię Pythona opartą na wcięciach z blokami Ruby, wszystko na Erlangu. Ale projektant zrezygnował z wrażliwości na wcięcia, a ten post, który napisał o tej decyzji, zawiera dyskusję o problemach, na które natrafił z wcięciami + bloki wieloliniowe, oraz zwiększone uznanie dla problemów / decyzji projektowych Guido:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html
Oto też interesująca propozycja bloków w stylu Ruby w Pythonie, gdzie natknąłem się na miejsce, w którym Guido publikuje odpowiedź bez jej zestrzelenia (choć nie jestem pewien, czy nastąpiła kolejna strzelanina):
http://tav.espians.com/ruby-style-blocks-in-python.html
źródło
[Edytuj] Przeczytaj tę odpowiedź. Wyjaśnia, dlaczego lambda wieloliniowa nie jest rzeczą.
Mówiąc najprościej, to nie jest mityczne. Z postu na blogu Guido van Rossuma:
źródło
Pozwól, że przedstawię ci chwalebny, ale przerażający hack:
Możesz teraz użyć tego
LET
formularza jako takiego:co daje:
[0, 3, 8]
źródło
Jestem winny praktykowania tego brudnego hacka w niektórych moich projektach, co jest nieco prostsze:
Mam nadzieję, że znajdziesz sposób, by pozostać pytonicznym, ale jeśli musisz to zrobić mniej bolesne niż używanie exec i manipulowanie globalsami.
źródło
Pozwól mi spróbować rozwiązać problem z analizowaniem @balpha. Używałbym nawiasów wokół wieloliniowej Lamdy. Jeśli nie ma nawiasów, definicja lambda jest zachłanna. Więc lambda w
zwraca funkcję, która zwraca
(y*z, [1,2,3])
Ale
znaczy
gdzie func to wielowierszowa lambda, która zwraca y * z. Czy to działa?
źródło
map(func, [1,2,3])
a dolny powinien być błędem, ponieważ funkcja mapy nie ma wystarczającej liczby argumentów. W kodzie jest też kilka dodatkowych nawiasów.(Dla każdego, kto nadal jest zainteresowany tym tematem.)
Zastanów się nad tym (obejmuje nawet użycie zwracanych wartości instrukcji w dalszych instrukcjach w „multilinicznej” lambdzie, chociaż jest to brzydkie do tego stopnia, że wymiotuje ;-)
źródło
state.clear()
ponieważ domyślne argumenty są tworzone tylko raz, gdy funkcja jest tworzona.Możesz po prostu użyć slash (
\
), jeśli masz wiele linii dla funkcji lambdaPrzykład:
źródło
Zaczynam od Pythona, ale najbardziej oczywistym sposobem jest wyodrębnienie wyrażenia jako funkcji ....
Skonstruowany przykład, wyrażenie wielokrotne
(x*2)
jest wyodrębniane jako funkcja i dlatego mogę używać multilinii:https://repl.it/@datracka/python-lambda-function
Być może nie odpowiada to dokładnie na pytanie, czy to był sposób wykonywania multilinii w samym wyrażeniu lambda , ale na wypadek, gdyby ktoś dostał ten wątek i szukał sposobu debugowania wyrażenia (jak ja), myślę, że to pomoże
źródło
map(multiply, [1, 2, 3])
?Jeśli chodzi o brzydkie hacki, zawsze możesz użyć kombinacji
exec
funkcji zwykłej i zwykłej, aby zdefiniować funkcję multilinii w następujący sposób:Możesz zawinąć to w funkcję taką jak:
źródło
Po prostu grałem trochę, aby spróbować zrozumieć dyktowanie z redukcją i wymyślić ten jeden liniowy hack:
Właśnie próbowałem zrobić to samo, co zrobiono w tym zrozumieniu języka JavaScript: https://stackoverflow.com/a/11068265
źródło
Oto bardziej interesujące wdrożenie wielu linii lambd. Nie jest to możliwe ze względu na to, jak Python używa wcięć jako sposobu strukturyzacji kodu.
Ale na szczęście dla nas formatowanie wcięć można wyłączyć za pomocą tablic i nawiasów.
Jak niektórzy już zauważyli, możesz napisać kod jako taki:
Teoretycznie, jeśli masz gwarancję oceny od lewej do prawej, to zadziałałoby, ale nadal tracisz wartości przekazywane z jednego wyrażenia na drugie.
Jednym ze sposobów osiągnięcia tego, co jest nieco bardziej szczegółowe, jest posiadanie
Gdzie każda lambda otrzymuje argumenty od poprzedniego.
Ta metoda pozwala napisać coś, co jest nieco seplenienie / schematem.
Możesz więc pisać takie rzeczy:
Do obliczenia przeciwprostokątnej można zastosować bardziej złożoną metodę
Spowoduje to zwrócenie listy liczb skalarnych, dzięki czemu można jej użyć do zmniejszenia wielu wartości do jednej.
Posiadanie tak wielu lambda z pewnością nie będzie bardzo wydajne, ale jeśli jesteś ograniczony, może to być dobry sposób na szybkie zrobienie czegoś, a następnie przepisanie go jako rzeczywistej funkcji później.
źródło
ponieważ funkcja lambda ma być jednowierszowa, ponieważ jest to najprostsza forma funkcji,
an entrance, then return
źródło