374

例外をスローするよりもネストされたループから抜け出す簡単な方法はありますか? (Perl では、各ループにラベルを付けて、少なくとも外側のループを続けることができます。)

for x in range(10):
    for y in range(10):
        print x*y
        if x*y > 50:
            "break both loops"

つまり、より良い方法はありますか:

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
4

8 に答える 8

903
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

同じことがより深いループでも機能します。

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
于 2009-03-17T12:27:02.140 に答える
192

少なくとも提案されましたが、却下されました。テストを繰り返すか、コードを再編成する以外に、別の方法はないと思います。時々少し面倒です。

拒否メッセージの中で、van Rossum 氏は の使用について言及しています。returnこれは非常に賢明であり、個人的に覚えておく必要があります。:)

于 2009-03-17T09:27:09.077 に答える
85

ループコードを関数に抽出できる場合は、returnステートメントを使用して、いつでも最も外側のループを終了できます。

def foo():
    for x in range(10):
        for y in range(10):
            print(x*y)
            if x*y > 50:
                return
foo()

その関数を抽出するのが難しい場合は、@ bjd2385が示唆するように、内部関数を使用できます。

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()
    ...
于 2009-03-17T12:37:59.680 に答える
59

itertools.productを使用してください!

from itertools import product
for x, y in product(range(10), range(10)):
    #do whatever you want
    break

Pythonドキュメントのitertools.productへのリンクは次のとおりです:http: //docs.python.org/library/itertools.html#itertools.product

また、2つのforが含まれる配列内包表記をループして、いつでも中断することができます。

>>> [(x, y) for y in ['y1', 'y2'] for x in ['x1', 'x2']]
[
    ('x1', 'y1'), ('x2', 'y1'),
    ('x1', 'y2'), ('x2', 'y2')
]
于 2011-10-26T17:47:19.470 に答える
46

ブール変数を使用することもあります。必要に応じて素朴ですが、非常に柔軟で読みやすいと思います。変数をテストすると、複雑な条件の再テストを避けることができ、内部ループでいくつかのテストから結果を収集することもできます。

    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
于 2011-05-16T20:50:55.047 に答える
23

例外を発生させる場合は、StopIteration 例外を発生させる可能性があります。それは少なくとも意図を明らかにするでしょう。

于 2012-08-14T00:31:38.450 に答える
8

ジェネレーターを使用するようにコードをリファクタリングすることもできます。ただし、これはすべてのタイプのネストされたループの解決策ではない場合があります。

于 2009-03-17T10:29:00.207 に答える
3

この特定のケースでは、itertools.productを使用して、ループを最新のpython(3.0およびおそらく2.6も)とマージできます。

私自身はこれを経験則としてとらえました。ネストするループが多すぎる場合(たとえば、2つ以上)、通常、このように、ループの1つを別のメソッドに抽出したり、ループを1つにマージしたりできます。場合。

于 2009-03-17T09:58:34.040 に答える