Pythonのインデントにハマる…

はじまり

みんなのPythonのサンプルコード写経中。
インデントの位置を間違えたので、Macの冷却ファンが大変なことに…(´・ω・`)
なお、このサンプルはみんなのPython第3版、チャプター07(P234)、ジェネレーター関数の定義のサンプルコードです。

間違い

def get_primes(x = 2):
    while True:
        for i in range(2,x):
            if x % i == 0:
                break
            else:
                yield x
            x += 1

i = get_primes()
for c in range(10):
    print(next(i))

!!注意!!
これは実行すると帰ってきません。

正しい

def get_primes(x = 2):
    while True:
        for i in range(2,x):
            if x % i == 0:
                break
        #ここのインデント位置が違う!
        else:
            yield x
        x += 1

i = get_primes()
for c in range(10):
    print(next(i))

forの中の「else」文のインデント位置だけが違うのだけど、
頭のなかには「else」と言ったら「if」という風にこびりついているので、
このように間違えた次第…。

よーく読むと、「if」に「else」をくっつけてしまうと、
無限ループしてしまうので、間違いなことは明白なのだけど。

for 〜 else とは

他の言語にはあまり見かけない珍しい機能として、Pythonにはforとwhileでelseを利用できます。
elseの役割は”for(while)のループ処理が完了した際に、実行される処理を記述する”ことです。
なお、breakでループを抜けたような場合にはelseは実行されません。
先ほどのコードの場合は、素数が見つかったら(ループが回りきったら)yieldで返却しています。
ifの中のbreakで抜けた場合は返却されません。(その場合はループを続行します。)

ただ、forでelseって…(´・ω・`) ほかに予約語作ればよかったんじゃね?