web-dev-qa-db-ja.com

Pythonでネストされた(二重)ループを解除する

次の方法を使用して、Pythonの二重ループを解除します。

for Word1 in buf1:
    find = False
    for Word2 in buf2:
        ...
        if res == res1:
            print "BINGO " + Word1 + ":" + Word2
            find = True
    if find:
        break

ダブルループを解除するより良い方法はありますか?

38
prosseek

おそらくあなたが望んでいるものではありませんが、通常はbreakfindに設定した後に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 

別の方法は、ジェネレーター式を使用してforを単一のループに押しつぶすことです

for Word1, Word2 in ((w1, w2) for w1 in buf1 for w2 in buf2):
    ... 
    if res == res1: 
        print "BINGO " + Word1 + ":" + Word2
        break 

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

Pythonネストされたループを壊すための推奨される方法は...例外です

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

ほとんどの場合、複数のメソッドを使用して、ダブルループと同じことを行う単一のループを作成できます。

あなたの例では、 itertools.product を使用して、コードスニペットを

import itertools
for Word1, Word2 in itertools.product(buf1, buf2):
    if Word1 == Word2:
        print "BINGO " + Word1 + ":" + Word2
        break

他のitertools関数は、他のパターンにも適しています。

10
magcius

「ビンゴ」を見つけたときに戻ることができるように、関数を使用してリファクタリングします。

ネストされたループの明示的なブレークアウトを許可する提案は拒否されました: http://www.python.org/dev/peps/pep-3136/

7
dkamins