web-dev-qa-db-fra.com

Briser la boucle imbriquée (double) dans Python

J'utilise la méthode suivante pour rompre 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

Existe-t-il une meilleure façon de rompre la double boucle?

38
prosseek

Probablement pas ce que vous espérez, mais vous voudrez généralement avoir un break après avoir défini find sur 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 consiste à utiliser une expression de générateur pour écraser le for dans 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 
45
John La Rooy

La manière recommandée dans Python pour casser les 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 
36
Guard

La plupart du temps, vous pouvez utiliser un certain nombre de méthodes pour créer une boucle unique qui fait la même chose qu'une boucle double.

Dans votre exemple, vous pouvez utiliser itertools.product 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 d'itertools conviennent également à d'autres modèles.

10
magcius

Refonte en utilisant des fonctions pour que vous puissiez revenir lorsque vous trouvez votre "bingo".

La proposition visant à autoriser l'éclatement explicite des boucles imbriquées a été rejetée: http://www.python.org/dev/peps/pep-3136/

7
dkamins