Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@moriyamanaoto

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

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ブロックを使わないこと

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?