Pythonのforとbreak循環構造にelse文を使うテクニック

2540 ワード

Pythonのwhileまたはforサイクルの後にelse子文があります。forサイクルの中でif条件が満たされていない場合、最後にelse文を実行します。

for i in range(5):
 if i == 1:
  print 'in for'
else:
 print 'in else'

print 'after for-loop'

# in for
# in else
# after for-loop

しかし、if条件はサイクル中に成立していることを発見しました。結局、else文の内容を実行しました。これはなぜですか?
はい、私達はこの時に次のプログラムを見ます。

for i in range(5):
 if i == 1:
  print 'in for'
  break
else:
 print 'in else'

print 'after for-loop'


# in for
# after for-loop

私たちはifにbreakを追加しました。これはelseがfor後に実行されるためですが、forサイクルが正常に終了した時だけelse文を実行します。サイクルがbreak文で中断された場合、elseは実行されません。
for/elseは下記のコードと同じです。C言語のようにflagsを追加できます。

found = False
for i in range(5):
 if i == 1:
  found = True
  print 'in for'
if not found:
 print 'not found'

print 'after for-loop'


# in for
# after for-loop

for文と似ていますが、while文のelse子文は同じように使われています。elseブロックはサイクル正常終了と循環条件不成立の時に実行されます。
条件語句if-elseについてはよく知っていますが、Pythonではfor-elseは処理に失敗しました。
例えば、私達はこのような機能を実現したいです。(81、99)の中で最大の完全な平方数を探して出力します。見つけられないなら、出力のヒントを出します。
c++のforサイクルで実現するなら、forサイクルが失敗したかどうかを手動で判断する必要があります。

#include <iostream> 
#include<math.h> 
using namespace std; 
int main() 
{ 
 int i; 
 float n; 
 for(i=99;i>81;i--) 
 { 
  n=sqrt((float)i); 
  if(n==int(n)) 
  { 
   cout<<i; 
   break; 
  } 
 } 
 if(i==81) //     
  cout<<"didn't find it!"<<endl; 
 return 0; 
} 

Pythonのfor-elseを使って簡単にこの機能を実現できます。

from math import sqrt 
for n in range(99,81,-1): 
 root = sqrt(n) 
 if root == int(root): 
  print n 
  break 
else: 
 print"Didn't find it!" 

forサイクルが完全に終わったらelseを実行します。途中でbreakから飛び出したら、elseと一緒に飛び出す。
特に注意したいのは、forにif文がある場合、elseのインデントは必ずforと揃え、ifと整合するとif-else文になり、思わぬエラーが発生します。

from math import sqrt 
for n in range(99,81,-1): 
 root = sqrt(n) 
 if root == int(root): 
  print n 
  break 
 else: 
  print"Didn't find it!" 

for-elseを使って2行のコードを節約して同時に読みやすいですが、if-elseと混同しやすいです。実際にはあまり使われていないようです。むしろ手動で処理する傾向があります。