19
def funcA(i):
   if i%3==0:
      print "Oh! No!",
      print i
      break

for i in range(100):
   funcA(i)
   print "Pass",
   print i

上記のスクリプトが機能しないことはわかっています。では、ブレーク付きの関数を配置したり、ループを続行したりする必要がある場合、どうすれば書くことができますか?

4

4 に答える 4

31

関数は、それが呼び出されたコードで中断または継続することはできません。中断/継続は、文字通りループ内に表示される必要があります。オプションは次のとおりです。

  1. funcA から値を返し、それを使用してブレークするかどうかを決定します
  2. funcA で例外を発生させ、呼び出しコード (または呼び出しチェーンの上位のどこか) でそれをキャッチします。
  3. ブレークロジックをカプセル化するジェネレーターを作成し、代わりにそれを反復処理しますrange

#3とは、次のような意味です。

def gen(base):
    for item in base:
        if item%3 == 0:
           break
        yield i

for i in gen(range(1, 100)):
    print "Pass," i

これにより、「ベース」反復子 (この場合は範囲​​) に基づいてジェネレーターにグループ化することで、条件を使用してブレークを設定できます。次に、範囲自体ではなく、このジェネレーターを反復処理すると、破壊的な動作が得られます。

于 2012-12-21T08:52:17.197 に答える
3

精巧なBrenBarnsの答え:break 幸いなことに伝播しません。break現在のループ、期間を中断することです。イベントを伝播する場合はraise、例外が必要です。ただし、例外を発生させてループを中断することは、ループを中断するための非常に醜い方法であり、コードを中断するための優れた方法です。

キス!最も簡単なのは、ループ内で直接状態をチェックすることです。

def my_condition(x):
  return x == 4

for i in xrange(100):
  if my_condition(i): break
  print i

何らかの理由で例外を伝播したい場合は、次のように使用します

# exception example
for i in xrange(100):
  if i == 4: raise Exception("Die!")
  print i

前述のように、それは本当に醜いデザインです。この例外をキャッチするのを忘れた、またはそのタイプをからExceptionに変更して、コードの上位部分のMyBreakExceptionどこかで変更するのを忘れたと想像してください...try/except

ジェネレーターの例にはメリットがあり、コードをより機能的なスタイルにします(私はこれを非常に気に入っています)

# generator example
def conditional_generator(n, condition):
  for i in xrange(n):
    if condition(i):
      break
    else:
      yield i


for i in conditional_generator( 100, my_condition ):
  print i

...これはtakewhile、eumiroによって言及されたに似ています

于 2012-12-21T09:18:45.930 に答える
1
def funcA(i):
   if i%3==0:
      print "Oh! No!",
      print i
      return True
   else:
      return False

for i in range(100):
   if funcA(i):
       break
   print "Pass",
   print i
于 2012-12-21T08:51:02.563 に答える
1

Break は関数間で伝播しません。ループ内のどこかに直接配置する必要があります。

于 2012-12-21T08:51:33.147 に答える