web-dev-qa-db-fra.com

python: lambda, déclaration de rendement/expression et boucles (préciser)

TLDR: Peut-on implémenter yield ou une instruction de générateur (avec une boucle) dans un lambda

Ma question est de clarifier:

Si la fonction de boucle simple suivante peut être mise en œuvre avec un rendement

def loopyield():
   for x in range(0,15):
      yield x
print(*loopyield())

Résultats en erreur:

lamyield=lambda x: yield x for x in range(0,15)
                       ^
SyntaxError: invalid syntax

On dirait qu’il s’attendait à quelque chose en tant qu’opérande correct pour une déclaration de retour non écrite, mais il a trouvé la variable yeild et se confondre.

Existe-t-il un moyen légitime de réaliser cela en boucle? 

Note latérale: yield peut être une déclaration/expression selon qui vous demandez: rendement - déclaration ou expression?

Réponse finale: Le rendement peut être utilisé avec lambda mais la limitation (une seule ligne) le rend inutile. for/while impossible dans lambda car ce ne sont pas des expressions. -user2357112 implicite pour la boucle est possible avec la compréhension de liste et le rendement est valide dans la compréhension de liste. -wim

Verdict- Les boucles explicites ne sont pas possibles car lambdas en python ne peut contenir que des expressions, et pour écrire une boucle explicite, vous devrez utiliser des instructions. -wim

13
theMobDog

Le one-liner que vous semblez essayer de créer est techniquement possible avec un lambda, il vous suffit d’aider un peu plus l’analyseur:

>>> lamyield = lambda: [(yield x) for x in range(15)]
>>> print(*lamyield())
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Ceci utilise implicitement une boucle for dans une compréhension de liste. Ce n'est pas possible avec une boucle explicite while ou for en dehors d'une compréhension. C'est parce que lambdas en python ne peut contenir que expressions , et pour écrire une boucle explicite, vous devrez utiliser statement .

Remarque: cette syntaxe est obsolète en Python 3.7 et déclenchera SyntaxError en Python 3.8

16
wim

Est-il nécessaire d'utiliser yeild à l'intérieur de lambda si vous pouvez le réécrire avec un générateur tel que?

In[1]: x = (i for i in range(15))
In[2]: x
Out[2]: <generator object <genexpr> at 0x7fbdc69c3f10>

In[3]: *x
Out[3]: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

In[4]: x = (i for i in range(0, 15))
In[5]: x.__next__()
Out[5]: 0

In[6]: next(x)
Out[6]: 1
0
N.C.