Pythonのfor-else
みんなのPython熟読中。ジェネレータの解説に出てきたコードでおもいっきりハマった。
#エラトステネスのふるい def get_prime(x=2): while True: for i in range(2,x): if x % i == 0: break else: yield x x += 1 i = get_prime() for c in range(5): print i.next()
↑をパッと見たときelseのインデント位置に違和感があったので↓の間違いだろうと思って
書き直して実行してみたらおかしなことになった。
def get_prime(x=2): while True: for i in range(2,x): if x % i == 0: break else: yield x x += 1 i = get_prime() for c in range(5): print i.next()
実行結果
3 5 5 5 7
まあ, コードをよく見直してみたら明らかにおかしいのはわかったんだけど,
「はあ?じゃあ, このelseは何だ?」とか思ったわけですよ。
明らかにfor文にかかってますからねぇ。で, ドキュメントを見たところ,
ループ文は else 節を持つことができます; else 節は、 (for で) 反復処理対象のリストを使い切ってループが終了したとき、または (while で) 条件が偽になったときに実行されますが、 break 文でループが終了したときは実行されません。
と書いてあった。何故にforにelse?とか思うのだけど, まあ, ほかにいい予約語がないと
言われればそんな気がしないでもない。ちなみに, 正しい実行結果は↓。
2 3 5 7 11
人によっては↓の方がわかりやすいかも?
def get_prime(x=2): while True: if not [i for i in range(2, x) if x % i == 0]: yield x x += 1
しかし, Pythonってインデントといい, タプルといい, リスト内包表記といい,
Haskellにかなり似てるなあ。動的(Python)か静的(Haskell)かの違いはあるけど。