Python whileステートメントのElse句


321

次のコードはPythonで有効であることに気づきました。私の質問はなぜですか?特定の理由はありますか?

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

5
@detly:ほとんどの人がこの構造を避けているからです。:)私は、GuidoがPy3kプロセスの最中に、少なくとも、elseこの使用のための単語の選択は著しく悪い考えであり、彼らがこれ以上それをしないだろうと述べたと思います。
ニコラスナイト

5
@Nicholas Knight-ええ、それは魅力的ですが、一見すると私だけが理解したものでしょう。その他の貧しい樹液は行くと言語の仕様を見て、または時間に戻って... Sta-のheeeeeyにここで質問を投稿しなければならない
detly

8
「else」を選択する背後にある考え方は、この構造がwhileループ内の「if X:break」と組み合わせて使用​​されることが多いということです。ループから抜け出さない場合は「else」句が実行されるので、「if」に対して「else」のようなものになります。
ジョナサンハートレイ

12
名前を変更する必要がありafter:ます。
naught101

回答:


388

elseお使いのとき句にのみ実行されwhileた条件が偽となります。breakループから抜けた場合、または例外が発生した場合は、実行されません。

これについて考える1つの方法は、条件に関する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()

42
「else句は、while条件がfalseになったときにのみ実行されます。」ここでの表現は、whileの状態がtrueからfalseの状態になり、elseよりも実行されることを意味します。ただし、whileが真にならない場合でも、else句は実行されます。
user597608 2014年

擬似コードは、私が間違っているのであれば、私を修正するが、これは全く同じであるwhile {} something 除くことをsomethingあなたならばスキップされますbreakwhileループ。
Daniel Kaplan 2015年

2
おそらく最も正確な疑似コードは次のようになります。while(True){if(cond){handle_true(); } else {handle_false(); ブレーク; }}
VinGarcia 2016

2
「合格しないで、200を集めないでください」、これは、これがどこから来たのかを知っている誰もが良い子供時代でした
Stefan Octavian

102

elseあなたはtryブロックの下をループ条件を打つか、落下により、通常のブロックを終了する場合句が実行されます。それはされていないあなたの場合に実行breakまたはreturnブロックのうち、または例外を発生させます。whileとforループだけでなく、ブロックを試すこともできます。

通常は、通常はループを早期に終了する場所にあり、ループの最後から実行されるのは予期しない/異常な状況です。たとえば、値を探してリストをループしている場合:

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

1
実際には、そのようなことのためにかなり便利な構成です。found_it=Falseループの最初に何回置いたか分からない、そしてfound_it最後にifチェックを行う
Cruncher

42

への返信として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が使用されない限り、ステートメントは最後に実行されます。

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


1
私は反対票を投じなかったが、誰かがなぜそうしたのか私は知っていると思う。あなたは質問に答えておらず、2行の説明だけで14行のコードを提供しています。質問に関連性がある場合は、私たちには言わないでください...
BlueEel

1
@BlueEelフィードバックをありがとう!コードについての説明を追加し、これが質問にどのように回答するかを明確にしました(コードの一部に回答するため)。
マーク

あなたはなんとかしてあなたのコードを前後関係に置くことができました、そしてあなたは私が今関連性を見るすべての質問に答えているわけではありません。初心者や初心者にも役立つようになりました(Pythonに関しては私自身)。-ありがとう、私は何かを学びました。
BlueEel 14

私は単純なアプリケーションが好きです-なぜ誰かがそれを使用するのかがわかります。私はそれの必要性を見たことがありませんが。
gabe

例ではfor / elseの使用を示していますが、問題は具体的にはwhile / else に関するものでした。
Ian Goldby

20

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

ドキュメントから:

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

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

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

break最初のスイートで実行した文を実行せずにループを終了else節のスイートを。continue最初のスイートで実行した文は、スイートの残りの部分をスキップし、表現のテストに戻ります。


15

私の答えは、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実行されません。


4

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

レイモンドヘッティンガーが言ったように、の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コードを理解するためにそれを読んでおり、その構文は私にとってはるかに理にかなっています。


3

else句は、while条件がfalseになったときにのみ実行されます。

ここではいくつかの例を示します。

例1:最初は条件がfalseであるため、else-clauseが実行されます。

i = 99999999

while i < 5:
    print(i)
    i += 1
else:
    print('this')

出力:

this

例2:しばらく-条件が i < 5あるため、偽になったことはありませんi == 3ループので、休憩他に、句が実行されませんでした。

i = 0

while i < 5:
    print(i)
    if i == 3:
        break
    i += 1
else:
    print('this')

出力:

0
1
2
3

例3:しばらく-条件が i < 5 falseの場合になっiたが5、そのほかの節が実行されました。

i = 0

while i < 5:
    print(i)
    i += 1
else:
    print('this')

出力:

0
1
2
3
4
this

0

else:文はwhileループは、もはやその条件を満たした場合にのみ、(あなたの例では、ときときに実行されるn != 0偽ではありません)。

したがって、出力は次のようになります。

5
4
3
2
1
what the...

私は知っていますが、この種のwhile / elseはJavaでは動作しません。Pythonで動作することがわかったとき、それは非常に興味深いものでした。私は好奇心旺盛で、技術的な理由を知りたかったのです。
Ivan、

6
@Ivan:それはあまりそうでないということではありません仕事を Javaでそれがないことが存在し、Javaで。誰かがそれを言語に追加することを気にかけていれば、それを機能させることができるでしょう。
Ignacio Vazquez-Abrams

1
いいえ、一方でFalse:.. else ..それでもelse句を実行します。言う方がより正確です。ループが壊れている場合のみ、elseは実行されません。
レオUfimtsev

0

それ以外の場合、whileループが中断しなかった場合に実行されます。

私はそれを「ランナー」という比喩で考えたいと思います。

「else」は、トラックの最初と最後のどちらから始めたかに関係なく、フィニッシュラインを越えるようなものです。「他には」だけされていないあなたはどこかの間に壊れた場合に実行します。

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

-1

Pythonでの「while:else:」のより適切な使用方法は、「while」でループが実行されない場合に「else」ステートメントが実行されることです。以下のコードを使用しても同じ結果が得られるため、今日の動作は意味がありません...

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

8
いいえ、違いは、またはキーワードelseを使用してループを終了する場合、ブロックが実行されないことです。あなたの例では、ループがコマンドで終了した場合にも実行されます。breakreturnprintbreak
notsurewhattodo 2013年

2
あなたは、ほとんどの人が機能が実際にどのように機能するのではなく、機能が機能することを望んでいるのかを説明します!
dotancohen 2016

-2

ソーシャルインタラクションに役立ちます。

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

2
そして、elseここの目的は正確には何ですか?コードはそれなしでもまったく同じことを行います。
wovano

breakカウントダウン中に時計とカレンダーを使用しないelseと、「新年あけましておめでとうございます!」即座には意味がありません。
ギムート

@ギモテ、「時計とカレンダーならbreak」ってどういう意味?breakコードにはありません。
wovano
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.