2011-12-07 8 views
12

私は最近、Javaのラベル付けループに関する解決策を持っていたthis questionを読んでいます。Pythonの命名ループ

このようなループネーミングシステムがPythonに存在するかどうかは疑問です。私はループの内側からforのループを外に出なければならない状況に何度も来ている。forループ。通常、この問題は、内部ループを、中断条件として使用されるブール値を返す関数に入れて解決します。しかし、折り返しのためのラベル付けループはずっと簡単に思えます。そのような機能がPythonに存在する場合、私はそれを試してみたいと思います。

誰にも分かりますか?

+0

[第2の回答](http://stackoverflow.com/questions/653509/breaking-out-of-nested-loops)、hopefullそれはいくつかの助けy。しかし私が見ることから、そのようなシステムは存在しません。 –

+0

"しかし、壊すためのラベル付けループはずっと簡単です"適切な機能よりも簡単ですか?どうして?これがどのように「よりシンプル」なのかの証拠をいくつか提出できますか? –

+1

私は便利な例はありませんが、その1つの場所でのみ使用される関数を作成しなければならない状況になります。たぶん「シンプル」は間違った言葉でした。私が意味していたことは、その1つの場所で使用するためだけに新しい関数を定義する必要はないということでした。 – inspectorG4dget

答えて

9

名前付きループをPython PEP3136に含める提案がありましたが、説明はhereで拒否されました。この拒否は、ほとんどが、コードの可読性がこの構造を含めることによって改善される稀な数の状況によるものであった。

1

いいえ。

何をしているかによって、itertoolsのものを使ってネストされたforループを単一のforループに平坦化することができます。

8

名前付きループ構造を言語構造に含める理由はありますが、読みやすさを損なうことなく簡単にPythonで回避できます。 Iは、(とりわけ) 戻る破壊条件として使用されるブール関数ことで内部ループを置くことによって、この問題を解決するためのPython

>>> try: 
    for i in xrange(0,5): 
     for j in xrange(0,6): 
      if i*j > 6: 
       print "Breaking" 
       raise StopIteration 
      print i," ",j 
except StopIteration: 
    print "Done" 


0 0 
0 1 
0 2 
0 3 
0 4 
0 5 
1 0 
1 1 
1 2 
1 3 
1 4 
1 5 
2 0 
2 1 
2 2 
2 3 
Breaking 
Done 
>>> 

で参照例の実装。

私はあなたがこれを試すべきだと思います。これは非常にpythonic、シンプルで読みやすいです。あなたが複数のループから抜け出すためにそれを使用することができます

import contextlib 

@contextlib.contextmanager 
def escapable(): 
    class Escape(RuntimeError): pass 
    class Unblock(object): 
     def escape(self): 
      raise Escape() 

    try: 
     yield Unblock() 
    except Escape: 
     pass 

:ここ

+2

+1。フロー制御の例外を使用することは、Pythonでは完璧に難題ですが、通常はパフォーマンス上の理由から、他の言語では悪いスタイルとみなされます。 – kindall

+2

外側のループを止めずに「続ける」だけの場合はどうすればいいですか? – Guillochon

+1

@ Guillochon try文を最初のforループの中に入れるだけです – Dylanthepiguy

6

は、コンテキストマネージャを使用して、複数の、ネストされたブロックから抜け出すための方法だ

with escapable() as a: 
    for i in xrange(30): 
     for j in xrange(30): 
      if i * j > 6: 
       a.escape() 

あなたも入れ子にすることができますそれら:

with escapable() as a: 
    for i in xrange(30): 
     with escapable() as b: 
      for j in xrange(30): 
       if i * j == 12: 
        b.escape() # Break partway out 
       if i * j == 40: 
        a.escape() # Break all the way out