comment n'en choisir qu'un seul élément à partir d'un générateur (en python)?
J'ai un générateur de fonction comme suit:
def myfunct():
...
yield result
L'habitude d'appeler cette fonction serait:
for r in myfunct():
dostuff(r)
Ma question, est-il un moyen d'obtenir qu'un élément de la génératrice à chaque fois que j'aime?
Par exemple, j'aimerais faire quelque chose comme:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
Vous devez vous connecter pour publier un commentaire.
Créer un générateur à l'aide de
Chaque fois que vous voulez un élément, utilisez
(ou
g.next()
dans Python 2.5 ou ci-dessous).Si le générateur de sort, il va augmenter
StopIteration
. Vous pouvez prendre cette exception, si nécessaire, ou de l'utilisation de ladefault
argumentnext()
:next(gen, default)
peut également être utilisé pour éviter lesStopIteration
exception. Par exemplenext(g, None)
pour un générateur de cordes, soit le rendement d'une chaîne ou d'Aucun après l'itération était fini.next(g)
. Cela va à l'interne appelg.__next__()
, mais vous n'avez pas vraiment à vous soucier de qui, tout comme vous n'avez généralement pas de soins quelen(a)
appelle en internea.__len__()
.g.next()
estg.__next__()
dans py3k. Le groupe builtinnext(iterator)
a été autour depuis la version 2.6 de Python, et c'est ce que devrait être utilisé dans tous les nouveaux code Python, et il est trivial de backimplement si vous avez besoin de soutien py <= 2.5.next()
et laStopIteration
exception dans leur excellente réponse.itertools.islice()
est un vrai bijou, joli et Pythonic, et il ne faut pas avoir peur de la boucle for en faveur des one-liners.next()
est fourni pour exactement cet effet, donc c'est la fonction naturelle à utiliser, et c'est ce que la plupart des gens utilisent à cette fin.next()
n'est pas que obscures. Je suis reconnaissant pour le conseil à propos de l'existence deislice()
, ce qui était exactement ce que je cherchais quand j'ai trouvé cette question.Pour la cueillette qu'un élément d'un générateur d'utilisation
break
dans unfor
déclaration, oulist(itertools.islice(gen, 1))
Selon votre exemple (littéralement), vous pouvez faire comme:
Si vous voulez "obtenir juste un élément de la [une fois généré] générateur à chaque fois que j'aime" (je suppose que 50% c'est l'intention d'origine, et la plus commune intention) puis:
De cette façon explicite l'utilisation de
generator.next()
peuvent être évités, et de fin de gestion des données ne nécessite pas (cryptique)StopIteration
la gestion des exceptions ou extra-valeur par défaut des comparaisons.La
else:
defor
section sur la déclaration n'est nécessaire que si vous voulez faire quelque chose de spécial en cas de fin de générateur.Note sur
next()
/.next()
:En Python3 le
.next()
méthode a été renommé.__next__()
pour une bonne raison: son faible niveau de PEP (3114). Avant de Python 2.6 la fonction builtinnext()
n'existe pas. Et il a même été discutée à déplacernext()
à laoperator
module (ce qui aurait été sage), en raison de sa rareté du besoin et discutable de l'inflation de builtin noms.À l'aide de
next()
sans défaut est encore très faible au niveau de la pratique de jeter le cryptiqueStopIteration
comme un boulon dans le bleu normal le code de l'application ouvertement. Et à l'aide denext()
par défaut sentinel - la meilleure qui doit être la seule option pour unnext()
directement dansbuiltins
- est limitée et donne souvent raison à bizarre non-pythonic logique/readablity.Ligne du bas: Utilisation de la fonction next() doit être très rare - comme l'utilisation de fonctions de
operator
module. À l'aide defor x in iterator
,islice
,list(iterator)
et d'autres fonctions de l'acceptation d'un itérateur de façon transparente est la façon naturelle de l'utilisation des itérateurs sur le niveau d'application - et pas toujours possible.next()
est de bas niveau, un concept, non évidente - comme la question de ce fil de discussion montre. Alors que par exemple à l'aide debreak
dansfor
est classique.mySeq.head
?Je ne crois pas qu'il y est un moyen pratique de récupérer une valeur arbitraire à partir d'un générateur. Le générateur fournira une méthode next() pour parcourir lui-même, mais l'ensemble de la séquence n'est pas produit immédiatement pour économiser de la mémoire. C'est la différence de fonctionnement entre un générateur et une liste.
assurez-vous d'attraper l'exception levée après le dernier élément est pris
Générateur est une fonction qui produit un itérateur. Par conséquent, une fois que vous avez itérateur exemple, l'utilisation next() pour récupérer l'élément suivant de l'itérateur.
Par exemple, utiliser la fonction next() pour récupérer le premier élément, et de les utiliser plus tard
for in
pour traiter les éléments restants:Je crois que c'est le seul moyen pour obtenir une liste à partir de l'itérateur, puis obtenir l'élément que vous voulez à partir de cette liste.
myfunct()
génère un grand nombre de valeurs), puisque vous pouvez utiliser la fonction intégréenext
pour obtenir la prochaine valeur générée.