Briser la boucle imbriquée (double) en Python [dupliquer]
Cette question a déjà une réponse ici:
- Comment sortir de plusieurs boucles en Python? 28 réponses
J'utilise la méthode suivante pour casser la double boucle en Python.
for word1 in buf1:
find = False
for word2 in buf2:
...
if res == res1:
print "BINGO " + word1 + ":" + word2
find = True
if find:
break
Est-il un meilleur moyen de briser la double boucle?
4 réponses
Probablement pas ce que vous espérez, mais généralement vous voudriez avoir un break
Après avoir défini find
à True
for word1 in buf1:
find = False
for word2 in buf2:
...
if res == res1:
print "BINGO " + word1 + ":" + word2
find = True
break # <-- break here too
if find:
break
Une autre façon est d'utiliser une expression de générateur pour écraser le for
en une seule boucle
for word1, word2 in ((w1, w2) for w1 in buf1 for w2 in buf2):
...
if res == res1:
print "BINGO " + word1 + ":" + word2
break
Vous pouvez également envisager d'utiliser itertools.product
from itertools import product
for word1, word2 in product(buf1, buf2):
...
if res == res1:
print "BINGO " + word1 + ":" + word2
break
La manière recommandée en Python pour casser des boucles imbriquées est... Exception
class Found(Exception): pass
try:
for i in range(100):
for j in range(1000):
for k in range(10000):
if i + j + k == 777:
raise Found
except Found:
print i, j, k
La plupart du temps, vous pouvez utiliser un certain nombre de méthodes pour créer une seule boucle qui fait la même chose qu'une double boucle.
Dans votre exemple, vous pouvez utiliser itertools.produit pour remplacer votre extrait de code par
import itertools
for word1, word2 in itertools.product(buf1, buf2):
if word1 == word2:
print "BINGO " + word1 + ":" + word2
break
Les autres fonctions itertools sont également bonnes pour d'autres modèles.
Refactor en utilisant des fonctions afin que vous puissiez revenir lorsque vous trouvez votre "bingo".
La proposition d'autoriser la rupture explicite des boucles imbriquées a été rejetée: http://www.python.org/dev/peps/pep-3136/