python forとelse文の面白い話


奥さんはプログラマーの夫に電話しました。「仕事が終わるとついでに饅頭を買ってきます。スイカを売っているのを見たら、一つ買います。」その夜、プログラマーの夫は肉まんを手に持って家に入りました。妻は怒って言いました。「どうして肉まんを買ったのですか?」夫は答えました。「スイカを売っているのを見たからです。」
プログラマーがスイカを買うという笑い話はたいていの読者が知っているかもしれません。今日書いたこの文章はこの笑い話と関係があります。
任意のプログラミング言語はif...else...文を提供しています。条件を満たせば、あることをします。そうでなければ、もう一つのことをします。

if a==b:
print("true")
else:
print("false")
しかし、Pythonではelseはifと組み合わせるだけでなく、もう一つの特有の構文はfor…else…というほかに、while、try…exceptと組み合わせて使うこともできます。

for i in range(3):
print(i)
else:
print("end")
>>>
0
1
2
end
しかし、for...else...if...else...とは違って、これまでの経験では、for文ブロックのコードはelseの中のコードを実行しません。逆も同じです。
しかし、私たちが見ているのは正反対です。forサイクルが終わってからまたelse文のブロックが実行されました。これはちょっと面白いです。if...else...白話に訳せば、そうでなければ、for...else...白話に翻訳されて、そして...なぜfor...then...と書かないのですか?これはよく分かりませんか?
また、forループが空のリストであってもelse文ブロックが実行されます。

for i in []:
print(i)
else:
print("end")
>>>
end
引き続き探索して、もしbreakでforサイクルを前倒ししたら、何が発生しますか?

for i in range(3):
print(i)
if i % 2 == 0:
break
else:
print("end")
>>>
0
ループがbreakに遭遇して終了すると、文全体が終了し、else文ブロックも実行されなくなります。
このように、サイクル中にbreakに遭遇しなかった場合に限ってelseブロックが実行されるという結論が得られます。今、あなたは分かりました。本当にelseと組み合わせて使うのはforサイクルの中のbreak、break…else…が二つの反発の条件です。
Pythonの父はなぜこのような文法飴を作ったのですか?これは私たち普通の人には理解できません。しかし、「pythonの禅」は答えを教えてくれました。「Although that way may not be obious at first unless you're Dutch.」
普段の開発ではfor...else...の応用シーンは本当に少ないですが、次のような場面でfor elseを使うのは本当にpythonicの使い方です。
リストの中の要素をforループで繰り返し検索すると、見つけたらすぐにループを終了します。反復終了リストが見つからない場合は、別の形式(例えば異常)でユーザーに通知する必要がある場合は、for...elseを使ってください。

# https://stackoverflow.com/a/9980752/1392860
for i in mylist:
if i == target:
break
process(i)
else:
raise ValueError("List argument missing terminal flag.")
for...elseを使わない場合は、すでに見つかったかどうかをマークするために臨時マーカー変数を作成する必要があります。

found = False
for i in mylist:
if i == target:
found = True
break
process(i)
if not found:
raise ValueError("List argument missing terminal flag.")
部屋で何かを探したい時は、どこかで見つけたら、捜査を続けることをやめます。部屋を全部ひっくり返しましたが、私たちが欲しいものがまだ見つからない時は、教えてください。すみません、ここにはあなたが探しているものがありません。このような場合はfor...elseを使います。それ以外は誤操作を起こす恐れがあります。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。