J'ai un générateur qui donne des nœuds d'un graphique acyclique dirigé (DAG), de profondeur d'abord: je peux itération sur les nœuds comme celui-ci p> Je voudrais pouvoir dire au générateur, de la boucle de la boucle, d'arrêter d'aller plus loin dans le graphique si une condition est remplie. p> Je suis venu avec la solution suivante qui utilise une fonction externe. p> Cette solution me force à déclarer des variables dont j'ai besoin avant que Stop_Crit soit défini alors ils peuvent être consultés de celui-ci. P> dans Ruby, le rendement renvoie la dernière expression du bloc de sorte que cela puisse être utilisé de manière commodément pour dire au générateur de continuer ou de s'arrêter. P> Quel est le meilleure façon d'atteindre cette fonctionnalité en python? p> p>
4 Réponses :
Coroutines (bassfriend les a mentionnés) sont difficiles pour les non initiés, alors voici un. J'ai ajouté du code de test pour que vous puissiez voir comment cela fonctionne vraiment. L'astuce est que si vous conservez les rôles de vos fonctions, où La prise en charge de Python pour les coroutines est un peu maladroite ( profond profond_first_search code> donne des nœuds, Vous vous retrouvez avec un horrible désordre ... à la place, les nœuds sont produits et envoyés em> au consommateur. P>
@coroutine code> à la rescousse). Il y a une jolie Nice Tutoriel pour Python et beaucoup de ressources pour les langues qui dépendent des coroutine, telles que Lua. De quelque manière que ce soit, c'est un concept très cool qui mérite d'explorer: -) p> p>
Normalement, vous ne dites pas votre iérien em> à vérifier les conditions, vous faites cela dans le corps de votre boucle: for node, depth in graph.depth_first_search():
if node meets condition:
# do something with node
break
# do something with node, its still referencing what you breaked on
Non, cela ne fonctionnerait pas, car cela empêcherait la boucle complètement. Ici, nous voulons arrêter l'algorithme de chercher plus profondément dans la branche actuelle, mais il reste peut-être d'autres branches à explorer. Voir Profondeur-première recherche .
solution naïf: Vous pouvez l'appeler normalement toujours, mais vous devez sauvegarder le démonteur pour avorter: p> i pense que cela fonctionne en ce moment. p> p>
Ceci est en fait un moyen courant de gâcher: it.send (1) code> envoie le 1, comme prévu, mais continue également
it code> à l'élément suivant - que vous seriez juste ignorer. Fondamentalement, vous devez dupliquer la boucle entière à nouveau dans le bloc de cesser de fumer, encore et encore. En fait, vous ne pouvez jamais mélanger l'envoi et l'itération de la même chose (vous traiteriez la chose en tant que générateur et une coroutine en même temps, ce qui n'a aucun sens).
Bien fixé, mais vous voulez break code> au lieu de
retour code> dans
profond profond_first_search code>
Si nous voulons abandonner le générateur complètement (ce que j'étais codé pour), nous avons besoin de retour code> car il y a 2
pour code> boucles.
Merci beaucoup pour vos réponses, David X et THC4K. Les coroutines sont en effet ce dont j'avais besoin. Puisqu'il.send (1) attend une réponse, un rendement supplémentaire est effectivement nécessaire ... Cette solution fait un it.Sutume () (implicite de la boucle de la boucle) et une it.send (1) lorsque la condition est rencontré. Ce serait bien de l'utiliser (1) ou it.send (0) Au lieu de cela, mais malheureusement, vous perdez la possibilité d'utiliser A pour boucle et que vous êtes obligé d'utiliser une boucle de temps. (Remarque: une pause est en effet nécessaire au lieu d'un retour si vous voulez explorer les nœuds restants)
@Mathieu, oh, donc c'est ce que le pause code> est pour; a du sens maintenant, merci. (Aussi
it.next () code> est équivalent à
it.send (aucun) code> si la mémoire sert.)
généralement dans Python, vous arrêteriez simplement de consommer le générateur et d'oublier. Point. (Ainsi, laissant des choses à la poubelle de la manière habituelle)
à l'aide de : p> générateur.close () code> Vous pouvez forcer un nettoyage de générateur immédiat déclenchant immédiatement toutes les finalisations. P>
Fonctionne comme un charme, merci! Voir docs.python.org/2.5/whatsnew/pep-342.htmlle A> Pour plus de détails sur Fermer ()