foo = lambda(x): v if (v = bar(x)) > 10 else 0
5 Réponses :
Preevaluate:
lambda x: next(res if res > 10 else 0 for res in (bar(x), ))
Ici, vous pouvez voir quelles sont les similitudes avec votre code:
lambda (x): foo(x) if foo(x) > 10 else 0 == (lambda(x): x if x > 10 else 0)(foo(x))
Ce que vous cherchez n'est pas possible à moins vous créez une sorte d'objet d'état mutable ou une autre astuce étrange.
La réponse @Alakazam est délicate et intelligente, utilisez-la à vos risques et périls. Il peut être préférable d'utiliser les itérateurs et next
pour éviter une liste intermédiaire supplémentaire:
foo = lambda(x): x if x > 10 else 0 result = foo(bar(x))
Ici vous avez le exemple en direct
Vous ne voudrez peut-être faire cela que si votre fonction est très longue à exécuter, sinon cela ne vous dérangera pas de l'exécuter deux fois. Vous ne pouvez pas utiliser la compréhension de liste .
foo = lambda x: [res if res> 10 else 0 for res in [bar (x)]] [0]
c'est mieux je pense: lambda x: next (res if res> 10 else 0 for res in (bar (x),))
, La raison en est que vous évitez l'allocation de mémoire intermédiaire
@Netwave Je ne pense pas que le malloc intermédiaire soit pertinent, même si cela dépend de la fonction, vous n'économisez pas beaucoup de mémoire.
Oui, vous pouvez éviter une double évaluation dans un lambda. Mais c'est vraiment moche et vous devriez l'éviter. Voici à quoi cela ressemble:
def foo(x): b = bar(x) return b if b > 10 else 0
Est-ce facile à lire et à comprendre? Non, absolument pas. Je ne vais pas l'expliquer; voyez si vous pouvez le comprendre. Ce n'est clairement pas une bonne solution, alors que devriez-vous faire à la place? Vous devriez utiliser une fonction réelle au lieu d'un lambda.
foo = lambda x: next(b if b > 10 else 0 for b in [bar(x)])
C'est beaucoup plus facile à lire et nettement meilleur.
Peut aussi bien définir une autre fonction:
def bar(x): # some expensive calculation <snip> def bar_threshold(x,t): y = bar(x) return y if y>t else 0 foo = lambda x: bar_threshold(x,10)
(ou redéfinir la barre, si vous vous trouvez en train de l'utiliser uniquement avec le seuil)
J'ai essayé de créer une fonction décorateur / wrapper ...
foo(10)
puis
foo(2)
puis j'essaye ... .:
foo = lambda x: bar(x)
donne-moi le résultat:
@funcdec def bar(x): return x * 2
retourne 0 et
def funcdec(func): def inner(x): if func(x) > 10: return func(x) else: return 0
renvoie 20
Vous pouvez stocker foo (x) dans une variable tmp et l'utiliser dans votre code.