J'ai entendu dire que les lambdas multilignes ne peuvent pas être ajoutés en Python car ils se heurteraient syntaxiquement aux autres constructions de syntaxe en Python. J'y pensais aujourd'hui dans le bus et j'ai réalisé que je ne pouvais pas penser à une seule construction Python avec laquelle les lambdas multilignes se heurtent. Étant donné que je connais assez bien la langue, cela m'a surpris.
Maintenant, je suis sûr que Guido avait une raison de ne pas inclure les lambdas multilignes dans la langue, mais par curiosité: dans quelle situation l'inclusion d'une lambda multilignes serait-elle ambiguë? Ce que j'ai entendu est-il vrai, ou y a-t-il une autre raison pour laquelle Python n'autorise pas les lambdas multilignes?
lambda
expressions en premier lieu; vous pouvez simplement utiliser desdef
instructions dans les expressions.Réponses:
Regardez ce qui suit:
Est-ce un lambda qui revient
(y, [1,2,3])
(donc la carte n'obtient qu'un seul paramètre, ce qui entraîne une erreur)? Ou revient-ily
? Ou s'agit-il d'une erreur de syntaxe, car la virgule sur la nouvelle ligne est mal placée? Comment Python saurait-il ce que vous voulez?Dans les parens, l'indentation n'a pas d'importance pour Python, vous ne pouvez donc pas travailler sans ambiguïté avec les multilignes.
Ceci est juste un simple, il y a probablement plus d'exemples.
la source
Guido van Rossum (l'inventeur de Python) répond lui-même à cette question exacte dans un ancien article de blog .
Fondamentalement, il admet que c'est théoriquement possible, mais que toute solution proposée serait non-Pythonique:
la source
C'est généralement très laid (mais parfois les alternatives sont encore plus laides), donc une solution de contournement consiste à faire une expression d'accolades:
Cependant, il n'acceptera aucune affectation, vous devrez donc préparer les données à l'avance. L'endroit que j'ai trouvé utile est le wrapper PySide, où vous avez parfois de courts rappels. Écrire des fonctions membres supplémentaires serait encore plus moche. Normalement, vous n'en aurez pas besoin.
Exemple:
la source
lambda arg
etsetattr(arg, 'attr','value')
de renverser "aucune affectation ...". Et puis il y a l'évaluation des courts-circuitsand
etor
... c'est le Javascript qui le fait. Plonge des racines en vous, comme du lierre dans un mur. J'espère presque que j'oublierai ça à Noël.PEP
directives)Quelques liens pertinents:
Pendant un certain temps, je suivais le développement de Reia, qui allait initialement avoir la syntaxe basée sur l'indentation de Python avec des blocs Ruby, le tout au-dessus d'Erlang. Mais, le concepteur a fini par abandonner la sensibilité à l'indentation, et ce post qu'il a écrit sur cette décision comprend une discussion sur les problèmes qu'il a rencontrés avec l'indentation + les blocs multi-lignes, et une appréciation accrue qu'il a acquise pour les problèmes / décisions de conception de Guido:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html
En outre, voici une proposition intéressante pour les blocs de style Ruby en Python que j'ai rencontré où Guido publie une réponse sans réellement l'abattre (cependant, je ne suis pas sûr qu'il y ait eu un abattage ultérieur):
http://tav.espians.com/ruby-style-blocks-in-python.html
la source
[Modifier] Lisez cette réponse. Cela explique pourquoi le lambda multiligne n'est pas une chose.
Autrement dit, c'est impythonique. Extrait du blog de Guido van Rossum:
la source
Permettez-moi de vous présenter un hack glorieux mais terrifiant:
Vous pouvez maintenant utiliser ce
LET
formulaire comme tel:qui donne:
[0, 3, 8]
la source
Je suis coupable de pratiquer ce sale hack dans certains de mes projets, ce qui est un peu plus simple:
J'espère que vous pouvez trouver un moyen de rester pythonique, mais si vous devez le faire, cela est moins douloureux que d'utiliser exec et de manipuler les globaux.
la source
Permettez-moi d'essayer de résoudre le problème d'analyse @balpha. J'utiliserais des parenthèses autour de la lamda multiligne. S'il n'y a pas de parenthèses, la définition lambda est gourmande. Donc, le lambda dans
renvoie une fonction qui renvoie
(y*z, [1,2,3])
Mais
veux dire
où func est le lambda multiligne qui renvoie y * z. Est-ce que ça marche?
la source
map(func, [1,2,3])
et celui du bas devrait être une erreur car la fonction map n'a pas assez d'arguments. Il y a aussi des parenthèses supplémentaires dans le code.(Pour toute personne encore intéressée par le sujet.)
Considérez ceci (inclut même l'utilisation des valeurs de retour des instructions dans d'autres instructions au sein du lambda "multiligne", bien que ce soit moche au point de vomir ;-)
la source
state.clear()
car les arguments par défaut ne sont créés qu'une seule fois lors de la création de la fonction.Vous pouvez simplement utiliser slash (
\
) si vous avez plusieurs lignes pour votre fonction lambdaExemple:
la source
Je commence par python mais venant de Javascript le moyen le plus évident est d'extraire l'expression en fonction ....
Exemple artificiel, l'expression multiplie
(x*2)
est extraite en fonction et je peux donc utiliser multiligne:https://repl.it/@datracka/python-lambda-function
Peut-être que cela ne répond pas exactement à la question si c'était comment faire la multiligne dans l'expression lambda elle - même , mais au cas où quelqu'un obtiendrait ce fil en cherchant comment déboguer l'expression (comme moi), je pense que cela aidera
la source
map(multiply, [1, 2, 3])
?Au sujet des hacks laids, vous pouvez toujours utiliser une combinaison de
exec
et une fonction régulière pour définir une fonction multiligne comme ceci:Vous pouvez envelopper cela dans une fonction comme:
la source
Je jouais juste un peu pour essayer de faire une compréhension de dict avec réduire, et arriver à ce hack d'une ligne:
J'essayais juste de faire la même chose que ce qui a été fait dans cette compréhension de dict Javascript: https://stackoverflow.com/a/11068265
la source
Voici une implémentation plus intéressante des lambdas multi-lignes. Ce n'est pas possible à réaliser à cause de la façon dont python utilise les retraits comme moyen de structurer le code.
Mais heureusement pour nous, le formatage en retrait peut être désactivé à l'aide de tableaux et de parenthèses.
Comme certains l'ont déjà souligné, vous pouvez écrire votre code comme tel:
En théorie, si vous êtes assuré d'avoir une évaluation de gauche à droite, cela fonctionnerait, mais vous perdez toujours des valeurs transmises d'une expression à une autre.
Une façon de réaliser ce qui est un peu plus verbeux est d’avoir
Où chaque lambda reçoit des arguments de la précédente.
Cette méthode vous permet d'écrire quelque chose qui ressemble un peu à un lisp / schéma.
Vous pouvez donc écrire des choses comme ceci:
Une méthode plus complexe pourrait être utilisée pour calculer l'hypoténuse
Cela renverra une liste de nombres scalaires afin qu'il puisse être utilisé pour réduire plusieurs valeurs à un.
Avoir autant de lambda ne sera certainement pas très efficace, mais si vous êtes contraint, cela peut être un bon moyen de faire quelque chose rapidement, puis de le réécrire en tant que fonction réelle plus tard.
la source
parce qu'une fonction lambda est censée être unilatérale, car c'est la forme la plus simple d'une fonction,
an entrance, then return
la source