web-dev-qa-db-fra.com

Instruction conditionnelle dans une fonction lambda d'une ligne en python?

Excuses si cela a été demandé auparavant, mais je ne pouvais le voir nulle part.

En gros, j'ai rencontré un scénario dans lequel je dois utiliser une instruction if dans une fonction lambda. Ce qui rend la tâche difficile, c’est que, idéalement, il doit figurer dans une seule ligne de code (si cela est même possible?)

Normalement, j'écrirais ceci:

T = 250

if (T > 200):
    rate = 200*exp(-T)
else:
    rate = 400*exp(-T)

return (rate)

Cependant, j'en ai besoin pour ressembler à ceci:

rate = lambda(T) : if (T>200): return(200*exp(-T)); else: return(400*exp(-T))

Je me rends compte que la chose la plus facile à faire serait de prendre la décision en dehors des fonctions lambda, puis d’avoir une fonction lambda séparée pour chaque cas, mais ce n’est pas vraiment approprié ici. Les fonctions lambda sont stockées dans un tableau et accédées en cas de besoin, chaque élément du tableau correspondant à un "débit" particulier, de sorte que deux rangées distinctes correspondant au même "débit" gâcheraient tout. Toute aide serait grandement appréciée, ou si ce n’était pas possible, une confirmation de la part d’autres serait bien :)

56
Nathan Bush

Utilisez le exp1 if cond else exp2 syntaxe.

rate = lambda T: 200*exp(-T) if T>200 else 400*exp(-T)

Notez que vous n'utilisez pas return dans les expressions lambda.

83
shx2

La bonne façon de faire est simple:

def rate(T):
    if (T > 200):
        return 200*exp(-T)
    else:
        return 400*exp(-T)

Il n'y a absolument aucun avantage à utiliser lambda ici. La seule chose pour laquelle lambda est utile est de vous permettre de créer des fonctions anonymes et de les utiliser dans une expression (par opposition à une instruction). Si vous assignez immédiatement le lambda à une variable, celle-ci n'est plus anonyme et est utilisée dans une instruction. Vous ne faites donc que rendre votre code moins lisible sans raison.

La fonction rate définie de cette façon peut être stockée dans un tableau, transmise, appelée, etc. de la même manière qu'une fonction lambda. Ce sera exactement la même chose (sauf un peu plus facile à déboguer, introspecter, etc.).


D'un commentaire:

Eh bien, la fonction devait s’intégrer dans une seule ligne, ce que je ne pensais pas pouvoir faire avec une fonction nommée?

Je ne peux imaginer aucune raison valable pour que la fonction doive être intégrée dans une seule ligne. Mais bien sûr, vous pouvez le faire avec une fonction nommée. Essayez ceci dans votre interprète:

>>> def foo(x): return x + 1

De plus, ces fonctions sont stockées sous forme de chaînes qui sont ensuite évaluées à l'aide de "eval", ce que je ne savais pas exactement comment faire avec les fonctions habituelles.

Encore une fois, même s’il est difficile d’être sûr à 100% sans savoir pourquoi, mais je suis au moins à 99% sûr que vous n’avez aucune raison ou une mauvaise raison pour cela. Presque chaque fois que vous pensez que vous voulez passer Python fonctionne comme des chaînes et appelez eval pour que vous puissiez les utiliser, vous voulez simplement passer Python fonctionne comme des fonctions et les utilise comme des fonctions.

Mais si ce n’est vraiment ce dont vous avez besoin ici, utilisez exec au lieu de eval.

Vous n'avez pas indiqué quelle version de Python vous utilisez. Dans 3.x, la fonction exec a exactement la même signature que la eval fonction:

exec(my_function_string, my_globals, my_locals)

En 2.7, exec est une instruction, pas une fonction - mais vous pouvez toujours l'écrire dans la même syntaxe que dans 3.x (tant que vous n'essayez pas d'attribuer la valeur de retour à rien) et cela fonctionne.

Dans les versions 2.x antérieures (avant la version 2.6, je pense?), Vous devez le faire comme ceci:

exec my_function_string in my_globals, my_locals
20
abarnert

Oui, vous pouvez utiliser la syntaxe abrégée pour les instructions if.

rate = lambda(t): (200 * exp(-t)) if t > 200 else (400 * exp(-t))

Notez que vous n'utilisez pas d'instructions return explicites dans lambdas.

7
Silas Ray

J'ai trouvé que je pourrais utiliser des déclarations "if-then" dans un lambda. Par exemple:

eval_op = {
    '|'  : lambda x,y: eval(y) if (eval(x)==0) else eval(x),
    '&'  : lambda x,y: 0 if (eval(x)==0) else eval(y),
    '<'  : lambda x,y: 1 if (eval(x)<eval(y)) else 0,
    '>'  : lambda x,y: 1 if (eval(x)>eval(y)) else 0,
}
5
pkmccroskey

Au moment où vous dites rate = lambda whatever... vous avez vaincu le point de lambda et vous devez définir une fonction. Mais si vous voulez un lambda, vous pouvez utiliser 'et' et 'ou'

lambda(T): (T>200) and (200*exp(-T)) or (400*exp(-T))
4
tdelaney