donc j'ai cet objet gen:
def yld123u(u):
for i in range(1, 4):
yield i * u
for i in yld123u(2):
print(i, end=' ')
que je ne peux utiliser que comme ça:
u = 2 # some user given value
for i in yld123cu:
print(i, end=' ')
y a-t-il une syntaxe à éviter la ligne supplémentaire avec u = .. affectation? comment mettre la valeur u dans l'instruction for?
Je voudrais quelque chose de similaire à ci-dessous, mais en utilisant l'expression gen, pas la fonction:
yld123cu = (x * u for x in range(1, 4))
p >
3 Réponses :
Vous pouvez utiliser lambda . Cela fonctionne pour moi:
yld123cu = lambda u: (x * u for x in range(1, 4))
for i in yld123cu(2):
print(i, end=' ')
merci Uli, mais cela en fait toujours une fonction. J'étais plus intéressé à le garder comme un objet générateur et à toujours pouvoir lui passer des paramètres avec une syntaxe semblable à un appel de fonction
Un lambda nommé est considéré comme une mauvaise pratique par PEP8
Merci @ OlivierMelançon pour cet indice. +1
Puisqu'une expression de générateur ne peut pas avoir sa propre portée, l'approche préférée serait de définir une fonction de générateur comme vous l'avez suggéré.
it = YieldReceive(yld123u(4))
for x in it:
print(x)
it.send(int(input('Enter next u value: ')))
Si vous devez mettre à jour u code > en cours de route et c'est la raison pour laquelle vous souhaitez éviter ce qui précède, sachez que vous pouvez envoyer une valeur à un générateur.
class YieldReceive:
stop_iteration = object()
def __init__(self, gen):
self.gen = gen
self.next = next(gen, self.stop_iteration)
def __iter__(self):
return self
def __next__(self):
if self.next is self.stop_iteration:
raise StopIteration
else:
return self.next
def send(self, value):
try:
self.next = self.gen.send(value)
except StopIteration:
self.next = self.stop_iteration
Le générateur se comporte toujours de la même manière si vous n'utilisez pas send.
XXX
4 0 12
Vous pouvez utiliser send pour mettre à jour la valeur de u .
gen = yld123u(4) v0 = next(gen) v1 = gen.send(0) v2 = gen.send(4) print(v0, v1, v2)
4 8 12
Si vous avez besoin du générateur pour interagir avec l'utilisateur entrée, voici une de mes réponses précédentes qui suggère un moyen d'implémenter un générateur de rendement-réception utilisable dans une boucle for .
for x in yld123u(4):
print(x)
def yld123u(u):
for i in range(1, 4):
received = yield i * u # a sent value will be assigned to 'received'
u = u if received is None else received
salut Olivier, merci beaucoup pour la perspicacité et les détails fantastiques! et le lien pour la méthode d'envoi aussi. J'ai joué toute la journée avec le débogueur pycharm qui m'enveloppait la tête .. donc les fonctions gen + send / next sont la voie à suivre, okey. Je n'ai étudié le python que quelques semaines après la famille C, je viens juste de passer à la partie oop hier, alors j'ai vraiment apprécié de parcourir votre échantillon de classe. c'est un travail si noble que vous faites si généreusement en aidant les gens, tout le meilleur pour vous !!
Vous pouvez essayer comme ça.
Remarque: Ici, nous n'avons pas de problème d'utilisation de la fonction lambda nommée.
2 4 6
ou
for i in (lambda u: (x * u for x in range(1, 4)))(2):
print(i, end=' ')
»Sortie
for i in (lambda u: (x * u for x in range(1, 4)))(u=2):
print(i, end=' ')
"id veut quelque chose de similaire à ci-dessous mais en utilisant l'expression gen, pas la fonction:" - pourquoi? C'est une solution parfaitement valable et fonctionnelle. Et dans les coulisses, il n'y a plus ou moins aucune différence entre les deux
merci les gars pour chaque réponse! appris quelque chose de chacun d'eux aujourd'hui. vraiment apprécié, site Web incroyable))