Briser la boucle imbriquée (double) en Python [dupliquer]

Cette question a déjà une réponse ici:

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?

31
demandé sur Peter Mortensen 2010-04-08 06:06:55

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 
39
répondu John La Rooy 2014-11-26 00:04:53

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 
31
répondu Guard 2010-12-29 11:06:31

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.

10
répondu magcius 2012-05-13 04:01:06

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/

6
répondu dkamins 2010-04-08 02:13:25