web-dev-qa-db-ja.com

Pythonのwhile文以外の節

私は以下のコードがPythonでは正当であることに気づきました。私の質問はなぜですか?具体的な理由はありますか?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."
270
Ivan

else句は、while条件が偽になったときにのみ実行されます。ループからbreakを呼び出した場合、または例外が発生した場合、それは実行されません。

それについて考える一つの方法は、条件に関してif/else構文としてである:

if condition:
    handle_true()
else:
    handle_false()

これはループ構造と似ています。

while condition:
    handle_true()
else:
    # condition is false now, handle and go on with the rest of the program
    handle_false()

例は次の通りです。

while value < threshold:
    if not process_acceptable_value(value):
        # something went wrong, exit the loop; don't pass go, don't collect 200
        break
    value = update(value)
else:
    # value >= threshold; pass go, collect 200
    handle_threshold_reached()
332
ars

else句は、通常の方法でブロックを終了した場合、ループ条件を打つかtryブロックの末尾から落ちて実行されます。 breakまたはreturnがブロック外にある場合、または例外が発生した場合は、notが実行されます。 whileループやループだけでなく、ブロックを試すこともできます。

通常、通常はループを早期に終了するような場所にあります。ループの終わりを過ぎると、予期しない/異常なことが起こります。たとえば、値を探すためにリストをループしているとします。

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("
85
John Kugelman

Is there a specific reason?への返信として、興味深いアプリケーションが1つあります。複数レベルのループから抜け出すことです。

これがどのように動作するかです:外側のループは最後にブレークがあるので、一度だけ実行されます。ただし、内側のループが完了すると(約数が見つからないと)、elseループに到達し、外側の区切りには到達しません。このように、内側のループの中断は、1つだけではなく両方のループから中断されます。

for k in [2, 3, 5, 7, 11, 13, 17, 25]:
    for m in range(2, 10):
        if k == m:
            continue
        print 'trying %s %% %s' % (k, m)
        if k % m == 0:
            print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
            break
    else:
        continue
    print 'breaking another level of loop'
    break
else:
    print 'no divisor could be found!'

whileforの両方のループで、elseが使用されていない限り、breakステートメントが最後に実行されます。

ほとんどの場合、これを実行するより良い方法(関数にラップする、または例外を発生させる)がありますが、これはうまくいきます!

36
Mark

Else条件は、while条件がfalseと評価されたときに実行されます。

のドキュメントから

式が真である限り、whileステートメントは繰り返し実行に使用されます。

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

これは式を繰り返しテストし、もしそれが真ならば、最初のスイートを実行します。式がfalseの場合(これが最初にテストされる可能性がある場合)、else句のスイートが存在する場合はそれが実行され、ループが終了します。

最初のスイートで実行されたbreakステートメントは、else句のスイートを実行せずにループを終了します。最初のスイートで実行されたcontinueステートメントは、スイートの残りをスキップして式のテストに戻ります。

18
Mark Rushakoff

私の答えは、私たちがwhile/for-elseで使えるときに焦点を当てます。

一見したところ、使用しても違いはないようです

while CONDITION:
    EXPRESSIONS
print 'ELSE'
print 'The next statement'

そして

while CONDITION:
    EXPRESSIONS
else:
    print 'ELSE'
print 'The next statement'

print 'ELSE'ステートメントは常に両方の場合(whileループが終了したときまたは実行されていないとき)に実行されるように思われるためです。

それで、それはステートメントprint 'ELSE'が実行されないときにのみ異なります。 breakの下のコードブロック内にwhileがある場合

In [17]: i = 0

In [18]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
else:
    print 'ELSE'
print 'The next statement'
   ....:
0
1
2
The next statement

異なる場合:

In [19]: i = 0

In [20]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
print 'ELSE'
print 'The next statement'
   ....:
0
1
2
ELSE
The next statement

returnはこのカテゴリには含まれていません。上記の2つの場合に同じ効果があるからです。

例外が発生しても、次のコードが実行される場所(例外はブロックを除く)が例外ハンドラ内にある場合、else句またはwhile句の直後のコードは実行されないため、差異は発生しません。

14
HVNSweeting

社会的な交流に役立ちます。

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")
2
Guimoute

これは古い質問ですが、...

レイモンド・ヘッティンガーが言ったように、それはwhile/no_breakではなくwhile/elseと呼ばれるべきです。
このスニペットを見ると、簡単に理解できます。

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
if n == 0:
    print n

ここで、whileループの後に条件をチェックする代わりに、elseと交換して、そのチェックを取り除くことができます。

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
else:  # read it as "no_break"
    print n

私は常にコードを理解するためにwhile/no_breakと読み、その構文は私にとってはるかに理にかなっています。

0
Iluvatar

Whileループが中断しなかった場合、Elseが実行されます。

私はそれを「ランナー」のメタファーで考えたいです。

「その他」はフィニッシュラインを越えるようなもので、トラックの最初から始めたのか最後から始めたのかは関係ありません。 "else"は、notが途中で中断した場合にのみ実行されます。

runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
    print("Runner at: ", runner_at)
    if runner_at == unlucky_sector:
        print("Runner fell and broke his foot. Will not reach finish.")
        break
    runner_at += 1
else:
    print("Runner has finished the race!") # Not executed if runner broke his foot.

主な使用例は、ネストされたループのこのブレークアウトを使用する場合、またはループがどこかでブレークしなかった場合にのみステートメントを実行する場合です(ブレークは異常な状況であると考えてください)。

たとえば、変数またはtry/catchを使用せずに内部ループから抜け出す方法のメカニズムは次のとおりです。

for i in [1,2,3]:
    for j in ['a', 'unlucky', 'c']:
        print(i, j)
        if j == 'unlucky':
            break
    else: 
        continue  # Only executed if inner loop didn't break.
    break         # This is only reached if inner loop 'breaked' out since continue didn't run. 

print("Finished")
# 1 a
# 1 b
# Finished
0
Leo Ufimtsev

else:ステートメントは、whileループが条件を満たさなくなったときにのみ実行されます(この例では、n != 0がfalseのとき)。

したがって、出力はこれになります。

5
4
3
2
1
what the...
0
BoltClock