Duplicate possible:
Comment sortir de plusieurs boucles en Python?
Existe-t-il un moyen plus simple de sortir des boucles imbriquées que de lancer une exception? (En Perl, vous pouvez attribuer des étiquettes à chaque boucle et au moins poursuivre une boucle externe.)
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
"break both loops"
C'est-à-dire, y a-t-il un moyen plus agréable que:
class BreakIt(Exception): pass
try:
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
raise BreakIt
except BreakIt:
pass
Cela a au moins été suggéré, mais aussi rejeté . Je ne pense pas qu'il existe un autre moyen, à moins de répéter le test ou de réorganiser le code. C'est parfois un peu agaçant.
Dans le message de rejet , M. van Rossum mentionne l'utilisation de return
, ce qui est très judicieux et que je dois me rappeler personnellement. :)
for x in xrange(10):
for y in xrange(10):
print x*y
if x*y > 50:
break
else:
continue # only executed if the inner loop did NOT break
break # only executed if the inner loop DID break
La même chose fonctionne pour les boucles plus profondes:
for x in xrange(10):
for y in xrange(10):
for z in xrange(10):
print x,y,z
if x*y*z == 30:
break
else:
continue
break
else:
continue
break
Si vous pouvez extraire le code de la boucle dans une fonction, vous pouvez utiliser une instruction return
pour quitter la boucle la plus externe à tout moment.
def foo():
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
return
foo()
S'il est difficile d'extraire cette fonction, vous pouvez utiliser une fonction interne, comme le suggère @ bjd2385, par exemple.
def your_outer_func():
...
def inner_func():
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
return
inner_func()
...
Utilisez itertools.product!
from itertools import product
for x, y in product(range(10), range(10)):
#do whatever you want
break
Voici un lien vers itertools.product dans la documentation python: http://docs.python.org/library/itertools.html#itertools.product
Vous pouvez également passer en boucle sur un tableau comprenant 2 fors et rompre à tout moment.
>>> [(x, y) for y in ['y1', 'y2'] for x in ['x1', 'x2']]
[
('x1', 'y1'), ('x2', 'y1'),
('x1', 'y2'), ('x2', 'y2')
]
(formaté pour plus de clarté)
Parfois, j'utilise une variable booléenne. Naïf, si vous voulez, mais je trouve ça assez souple et confortable à lire. Tester une variable peut éviter de tester à nouveau des conditions complexes et peut également collecter les résultats de plusieurs tests effectués dans des boucles internes.
x_loop_must_break = False
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
x_loop_must_break = True
break
if x_loop_must_break: break
Si vous souhaitez déclencher une exception, vous pouvez également déclencher une exception StopIteration . Cela rend au moins l'intention évidente.
Vous pouvez également refactoriser votre code pour utiliser un générateur. Mais cela peut ne pas être une solution pour tous les types de boucles imbriquées.
Dans ce cas particulier, vous pouvez fusionner les boucles avec un python moderne (3.0 et probablement 2.6 également) en utilisant itertools.product.
Pour ma part, j’ai pris cela comme une règle de base. Si vous emboîtez trop de boucles (comme dans plus de 2), vous êtes généralement en mesure d’extraire l’une des boucles dans une méthode différente ou de fusionner les boucles en une seule, comme dans cet exemple. Cas.