1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Effective Python メモ 項目12 forとwhileループの後のelseブロックは使うのを避ける

Last updated at Posted at 2016-03-24

https://www.oreilly.co.jp/books/9784873117560/
P23~25

(pythonだけ)elseブロックの落とし穴!

通常、プログラミング言語におけるelseブロックは主に「上部のブロックが実装されなかったら、これを実行しなさい」という意味合いで使われていると思います。
しかし、pythonでは違います

for i in range(3):
    print('Loop %d' % i)
else:
    print('Else block')

>>>
Loop 0
Loop 1
Loop 2
Else block

このように、forループが実行完了したあとにelseブロックが実行されています。
また、直前にbreakが実行された場合はelseブロックは実行されないという謎仕様

for i in range(3):
    print('Loop %d' % i)
    if i == 1:
        break
else:
    print('Else block')

>>>
Loop 0
Loop 1

さらに、空のシーケンスをループすると、elseブロックがすぐに実行される

for i in []:
    print('Never runs')
else:
    print('Else block')

>>>
Else block

さらにさらに、whileループの頭で失敗した場合はそのまま実行される

while False:
    print('Never runs')
else:
    print('Else block')

>>>

Else block

謎仕様の使いみち

ループ後の情報を処理する場合に使いみちがある。
例えば、2つの数字が互いに素(公約数が1位外に無い)かどうかを調べる際に、あらゆる数字を試す道中で公約数が見つかる場合は素でないと判断できるが、最後までループを回しても見つからなかった場合は素であると判断できる。ここでこの仕様は役に立つ。

a = 4
b = 9

for i in range(2, min(a, b) + 1):
    print('Tasting', i)
    if a % i == 0 and b % i ==0:
        print('Not coprime')
        break
else:
    print('Coprime')

>>>
Tasting 2
Tasting 3
Tasting 4
Coprime

ようは、前のブロックがbreak判定がある場合にしか役に立たないと思われる。

だったら別途ヘルパー関数を書くなりして、もっとスマートなやり方にするべきでしょう。

結論なるべくループでelseブロックを使わないこと

1
1
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?