Existe-t-il un moyen d'effectuer "si" dans le lambda de python

359

En python 2.6 , je veux faire:

f = lambda x: if x==2 print x else raise Exception()
f(2) #should print "2"
f(3) #should throw an exception

Ce n'est clairement pas la syntaxe. Est-il possible d'effectuer un ifin lambdaet si oui, comment le faire?

Merci

Gars
la source
2
Vous ne pouvez pas imprimer ou augmenter dans un lambda. Les lambdas ne sont que des fonctions, vous pouvez toujours utiliser une fonction à la place.
Lennart Regebro
10
Je ne suis pas d'accord avec vous. J'ai besoin de 4 fonctions différentes et très courtes comme celle ci-dessus qui doivent être mises dans une liste / dictionnaire afin que je puisse les parcourir et sélectionner celles à utiliser dans chaque itération. Au lieu de nombreuses lignes de code de juste inits, avant l'itération, je peux le ramener à seulement 4 lignes de code init. Moins on est de fous.
Guy
5
4 lignes de code ne sont pas une solution louable lorsque d'autres personnes doivent lire, interpréter, comprendre et maintenir le code. De plus, le problème "print / raise" dans l'exemple montre ce qui ne peut pas et ne doit pas être fait dans lambdas.
S.Lott
Les lambdas @LennartRegebro ne sont pas des fonctions en python, ce ne sont que des expressions, c'est pourquoi il y a beaucoup de choses que vous ne pouvez pas faire avec elles.
Aaron McMillin
1
@AaronMcMillin Lambdas sont des fonctions. Ils sont limités aux expressions pour des raisons de syntaxe, mais ce sont des fonctions.
Lennart Regebro

Réponses:

661

La syntaxe que vous recherchez:

lambda x: True if x % 2 == 0 else False

Mais vous ne pouvez pas utiliser printou raisedans un lambda.

Robert Rossney
la source
33
en python 3, vous pouvez utiliser print
recursive
11
Bien sûr, mais la question était "comment puis-je l'utiliser ifdans une lambda?" pas "quelle est la meilleure façon d'écrire un lambda qui renvoie True si un nombre est pair?"
Robert Rossney
99
C'est une horrible syntaxe - facilement la pire construction du langage Python, approchant les niveaux d'absurdité de Perl dans son évaluation hors service - mais c'est ce qui était demandé. Vous votez sérieusement contre les réponses pour être correct?
Glenn Maynard
41
C'est la bonne réponse à la question "Comment écrire une fonction lambda qui me dit si un nombre est pair?" Ce n'est cependant pas une bonne réponse à la question que le PO avait initialement posée. Même si vous n'aimez pas l'exemple que j'ai inventé, mon message répond en fait clairement à la question du PO.
Robert Rossney
10
Il est douloureusement évident que quiconque suggère "x% 2 == 0" - ou vote un commentaire le recommandant, ce qui fait au moins sept personnes - n'a même pas lu la question d'origine.
Glenn Maynard
40

pourquoi ne définissez-vous pas simplement une fonction?

def f(x):
    if x == 2:
        print(x)
    else:
        raise ValueError

il n'y a vraiment aucune justification à utiliser lambda dans ce cas.

SilentGhost
la source
3
printn'est pas encore une fonction en 2.6. :)
Lukáš Lalinský
7
@ Lukáš Lalinský: cela fonctionne toujours en 2.x. il sera traité comme une paire de parenthèses redondantes
newacct
24
Vous ne connaissez pas son cas d'utilisation réel, il n'y a donc aucun moyen de dire qu'il n'y a aucune raison d'utiliser un lambda.
Glenn Maynard
6
@Glenn Maynard: Il n'y a presque aucune raison d'utiliser un lambda, point final. Assigner un lambda à une variable - en tant que substitut def- est généralement une très mauvaise idée (tm). Il suffit d'utiliser un defsimple programmeur mortel qui peut le lire, l'interpréter, le comprendre et le maintenir.
S.Lott
17
Il existe de nombreuses utilisations légitimes des lambdas. Si vous n'y pensez pas, ce n'est pas la faute de lambda. (Je ne suis pas un fan de la syntaxe elle-même, bien sûr - c'est une solution de contournement maladroite pour le fait que la syntaxe d'indentation mal conçue de Python ne peut pas gérer les fonctions en ligne comme les langages normaux.)
Glenn Maynard
25

Probablement la pire ligne de python que j'ai écrite jusqu'à présent:

f = lambda x: sys.stdout.write(["2\n",][2*(x==2)-2])

Si x == 2 vous imprimez,

si x! = 2 vous relancez.

jimifiki
la source
bravo, je pense que c'est la seule réponse sur la page qui répond réellement à la question
theEpsilon
22

Vous pouvez facilement lever une exception dans un lambda, si c'est ce que vous voulez vraiment faire.

def Raise(exception):
    raise exception
x = lambda y: 1 if y < 2 else Raise(ValueError("invalid value"))

Est-ce une bonne idée? Mon instinct en général est de laisser les rapports d'erreur hors des lambdas; laissez-lui la valeur None et déclenchez l'erreur dans l'appelant. Je ne pense pas que ce soit intrinsèquement mauvais, cependant - je considère que la syntaxe "y si x sinon z" elle-même est pire - assurez-vous simplement que vous n'essayez pas de trop envelopper dans un corps lambda.

Glenn Maynard
la source
1
L'augmenter dans un appelant est probablement la plus jolie méthode si vous me demandez.
Dominic Bou-Samra
Peut-être, mais cela dépend fortement du cas particulier. Bien sûr, vous pouvez également décorer le lambda après l'avoir créé. x = RaiseValueErrorOnNone(x), encore une fois, selon le cas.
Glenn Maynard
15

Les lambdas en Python sont assez restrictifs en ce qui concerne ce que vous êtes autorisé à utiliser. Plus précisément, vous ne pouvez pas avoir des mots - clés ( à l' exception des opérateurs comme and, not, or, etc.) dans leur corps.

Donc, il n'y a aucun moyen d'utiliser un lambda pour votre exemple (parce que vous ne pouvez pas l'utiliser raise), mais si vous êtes prêt à concéder cela ... Vous pouvez utiliser:

f = lambda x: x == 2 and x or None
David Wolever
la source
16
La restriction spécifique de lambda est que vous n'êtes pas autorisé à utiliser des instructions, uniquement des expressions.
Daniel Werner
13

notez que vous pouvez en utiliser plusieurs autres ... if dans votre définition lambda:

f = lambda x: 1 if x>0 else 0 if x ==0 else -1
filotn
la source
2

Si vous voulez toujours imprimer, vous pouvez importer le futur module

from __future__ import print_function

f = lambda x: print(x) if x%2 == 0 else False
Juan Pablo Lopez
la source
2

Vous pouvez également utiliser des opérateurs logiques pour avoir quelque chose comme un conditionnel

func = lambda element: (expression and DoSomething) or DoSomethingIfExpressionIsFalse

Vous pouvez en savoir plus sur les opérateurs logiques ici

Victor Lucas
la source
Cela ne va pas avec la philosophie de python en termes de clarté. Même si elle est logiquement équivalente, la ifsyntaxe est toujours préférée à cela. La manière évidente de vérifier les conditions.
0xc0de
Je vous remercie! Je l'ai utilisé dans un travail de langage fonctionnel à l'université en raison des restrictions imposées par le professeur qui dit que je ne pouvais pas utiliser la ifdéclaration, j'ai donc trouvé ce moyen pas évident .
Victor Lucas
2

ce dont vous avez besoin exactement

def fun():
    raise Exception()
f = lambda x:print x if x==2 else fun()

appelez maintenant la fonction comme vous le souhaitez

f(2)
f(3)
Manjunath Bhadrannavar
la source
2

Cet extrait devrait vous aider à:

x = lambda age: 'Older' if age > 30 else 'Younger'

print(x(40))
Adarsh ​​Somasundar
la source
0

L'exemple de code suivant fonctionne pour moi. Je ne sais pas si cela se rapporte directement à cette question, mais j'espère que cela aide dans d'autres cas.

a = ''.join(map(lambda x: str(x*2) if x%2==0 else "", range(10)))
Rahul
la source
0

Essayez-le:

is_even = lambda x: True if x % 2 == 0 else False
print(is_even(10))
print(is_even(11))

En dehors:

True
False
Benyamin Jafari
la source
0

Un moyen simple d'effectuer un if dans lambda est d'utiliser la compréhension de liste.

Vous ne pouvez pas lever d'exception dans lambda, mais c'est un moyen dans Python 3.x de faire quelque chose de proche de votre exemple:

f = lambda x: print(x) if x==2 else print("exception")

Un autre exemple:

retourner 1 si M sinon 0

f = lambda x: 1 if x=="M" else 0
Paul Cysne
la source