Ich habe gehört, dass mehrzeilige Lambdas in Python nicht hinzugefügt werden können, da sie syntaktisch mit den anderen Syntaxkonstrukten in Python kollidieren würden. Ich habe heute im Bus darüber nachgedacht und festgestellt, dass ich mir kein einziges Python-Konstrukt vorstellen kann, mit dem mehrzeilige Lambdas in Konflikt geraten. Da ich die Sprache ziemlich gut kenne, hat mich das überrascht.
Ich bin mir sicher, dass Guido einen Grund hatte, mehrzeilige Lambdas nicht in die Sprache aufzunehmen, aber aus Neugier: In welcher Situation wäre die Aufnahme eines mehrzeiligen Lambdas mehrdeutig? Ist das, was ich gehört habe, wahr oder gibt es einen anderen Grund, warum Python keine mehrzeiligen Lambdas zulässt?
lambda
Ausdrücke. Sie können einfachdef
Anweisungen in Ausdrücken verwenden.Antworten:
Schauen Sie sich Folgendes an:
Ist dies ein Lambda, das zurückkehrt
(y, [1,2,3])
(daher erhält map nur einen Parameter, was zu einem Fehler führt)? Oder kehrt es zurücky
? Oder handelt es sich um einen Syntaxfehler, weil das Komma in der neuen Zeile falsch platziert ist? Wie würde Python wissen, was Sie wollen?Innerhalb der Parens spielt die Einrückung für Python keine Rolle, sodass Sie nicht eindeutig mit Multilines arbeiten können.
Dies ist nur eine einfache, es gibt wahrscheinlich mehr Beispiele.
quelle
Guido van Rossum (der Erfinder von Python) beantwortet genau diese Frage selbst in einem alten Blog-Beitrag .
Grundsätzlich gibt er zu, dass es theoretisch möglich ist, aber dass jede vorgeschlagene Lösung nicht pythonisch wäre:
quelle
Dies ist im Allgemeinen sehr hässlich (aber manchmal sind die Alternativen sogar noch hässlicher). Eine Problemumgehung besteht darin, einen Ausdruck in geschweiften Klammern zu erstellen:
Es werden jedoch keine Zuweisungen akzeptiert, sodass Sie die Daten im Voraus vorbereiten müssen. Der Ort, an dem ich dies nützlich fand, ist der PySide-Wrapper, bei dem manchmal kurze Rückrufe auftreten. Das Schreiben zusätzlicher Mitgliedsfunktionen wäre noch hässlicher. Normalerweise brauchen Sie das nicht.
Beispiel:
quelle
lambda arg
undsetattr(arg, 'attr','value')
zu untergraben. Und dann gibt es eine Kurzschlussauswertung vonand
undor
... es ist das Javascript, das das macht. Versenkt Wurzeln in dir, wie Efeu in eine Wand. Ich hoffe fast, dass ich das über Weihnachten vergesse.PEP
Richtlinien befolgen )Einige relevante Links:
Eine Weile verfolgte ich die Entwicklung von Reia, das ursprünglich Pythons einrückungsbasierte Syntax mit Ruby-Blöcken auf Erlang enthalten sollte. Der Designer gab jedoch die Einrückempfindlichkeit auf, und dieser Beitrag, den er über diese Entscheidung schrieb, enthielt eine Diskussion über Probleme, auf die er mit Einrückungen + mehrzeiligen Blöcken stieß, und eine erhöhte Wertschätzung, die er für Guidos Designprobleme / -entscheidungen erhielt:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html
Hier ist auch ein interessanter Vorschlag für Ruby-ähnliche Blöcke in Python, auf die Guido gestoßen ist, wo Guido eine Antwort veröffentlicht, ohne sie tatsächlich abzuschießen (ich bin mir jedoch nicht sicher, ob es einen nachfolgenden Abschuss gegeben hat):
http://tav.espians.com/ruby-style-blocks-in-python.html
quelle
[Bearbeiten] Lesen Sie diese Antwort. Es erklärt, warum mehrzeiliges Lambda keine Sache ist.
Einfach gesagt, es ist unpythonisch. Aus Guido van Rossums Blogbeitrag:
quelle
Lassen Sie mich Ihnen einen herrlichen, aber schrecklichen Hack präsentieren:
Sie können dieses
LET
Formular jetzt als solches verwenden:was gibt:
[0, 3, 8]
quelle
Ich bin schuldig, diesen schmutzigen Hack in einigen meiner Projekte geübt zu haben, was etwas einfacher ist:
Ich hoffe, Sie können einen Weg finden, um pythonisch zu bleiben, aber wenn Sie dies tun müssen, ist dies weniger schmerzhaft als die Verwendung von exec und die Manipulation von Globals.
quelle
Lassen Sie mich versuchen, das @ balpha-Parsing-Problem anzugehen. Ich würde Klammern um die mehrzeilige Lamda verwenden. Wenn es keine Klammern gibt, ist die Lambda-Definition gierig. Also das Lambda rein
Gibt eine Funktion zurück, die zurückgibt
(y*z, [1,2,3])
Aber
meint
Dabei ist func das mehrzeilige Lambda, das y * z zurückgibt. Funktioniert es?
quelle
map(func, [1,2,3])
und der untere sollte ein Fehler sein, weil die Map-Funktion nicht genügend Argumente hat. Außerdem enthält der Code einige zusätzliche Klammern.(Für alle, die sich noch für das Thema interessieren.)
Bedenken Sie dies (schließt sogar die Verwendung der Rückgabewerte von Anweisungen in weiteren Anweisungen innerhalb des "mehrzeiligen" Lambda ein, obwohl es bis zum Erbrechen hässlich ist ;-)
quelle
state.clear()
da Standardargumente beim Erstellen der Funktion nur einmal erstellt werden.Sie können einfach slash (
\
) verwenden, wenn Sie mehrere Zeilen für Ihre Lambda-Funktion habenBeispiel:
quelle
Ich beginne mit Python, aber wenn ich aus Javascript komme, ist es am offensichtlichsten, den Ausdruck als Funktion zu extrahieren.
Erfundenes Beispiel, Multiplikationsausdruck
(x*2)
wird als Funktion extrahiert und daher kann ich Multiline verwenden:https://repl.it/@datracka/python-lambda-function
Vielleicht beantwortet es nicht genau die Frage, ob dies die Mehrzeiligkeit des Lambda-Ausdrucks selbst ist , aber falls jemand diesen Thread erhält, der nach dem Debuggen des Ausdrucks sucht (wie ich), denke ich, dass es helfen wird
quelle
map(multiply, [1, 2, 3])
?Bei hässlichen Hacks können Sie immer eine Kombination aus
exec
und eine reguläre Funktion verwenden, um eine mehrzeilige Funktion wie die folgende zu definieren:Sie können dies in eine Funktion wie die folgende einbinden:
quelle
Ich habe nur ein bisschen gespielt, um zu versuchen, ein Diktatverständnis mit Reduzieren zu machen, und mir diesen One-Liner-Hack ausgedacht:
Ich habe nur versucht, dasselbe zu tun wie in diesem Javascript-Diktat: https://stackoverflow.com/a/11068265
quelle
Hier ist eine interessantere Implementierung von mehrzeiligen Lambdas. Dies ist nicht möglich, da Python Einrückungen zum Strukturieren von Code verwendet.
Glücklicherweise kann die Formatierung von Einzügen mithilfe von Arrays und Klammern deaktiviert werden.
Wie einige bereits betont haben, können Sie Ihren Code als solchen schreiben:
Theoretisch würde es funktionieren, wenn Sie garantiert eine Bewertung von links nach rechts haben, aber Sie verlieren immer noch Werte, die von einem Ausdruck an einen anderen übergeben werden.
Ein Weg, um das zu erreichen, was etwas ausführlicher ist, ist zu haben
Wobei jedes Lambda Argumente vom vorherigen erhält.
Mit dieser Methode können Sie etwas schreiben, das ein bisschen lisp / Schema ist.
Sie können also Folgendes schreiben:
Eine komplexere Methode könnte verwendet werden, um die Hypotenuse zu berechnen
Dadurch wird eine Liste mit skalaren Zahlen zurückgegeben, sodass mehrere Werte auf einen reduziert werden können.
So viele Lambda zu haben, wird sicherlich nicht sehr effizient sein, aber wenn Sie eingeschränkt sind, kann dies eine gute Möglichkeit sein, etwas schnell zu erledigen und es später als tatsächliche Funktion neu zu schreiben.
quelle
weil eine Lambda-Funktion einzeilig sein soll, da sie die einfachste Form einer Funktion ist,
an entrance, then return
quelle