for文はwhile文と同じ繰り返し処理をするための構文です。
ここでは「forとwhileの違いは何?」「for文の使い方が知りたい」といった方へ、for文の使い方を解説します。
YouTubeも公開していますので、動画や音声で聞きたい方はぜひご覧ください。
forの基本的な使い方
ではforの基本的な使い方を見ていきましょう。
といってもforは基本的にはwhileと同じ繰り返し処理です。では何が違うかと言うと、for文は「リストや辞書などのイテラブルの処理」に長けていることです。
例を見てみましょう。forは次のように書きます。
list = ["Hello", "Python", "World!"]
str = ""
for s in list:
str += s + " "
print(str)
[出力結果]
Hello Python World!
これは「リスト内の文字列を結合して出力する」プログラムです。
変数listには3つの文字列が格納されています。それをfor文で繰り返し処理しています。forの後に続くsは、繰り返しのたびにリストから値を一つずつ取り出すための変数です。この変数sを、あらかじめ用意しておいた変数strに文字列結合の演算子で一つずつ結合し、最後に出力して終了です。
上記のコードはwhileで書くとこうなります。
list = ["Hello", "Python", "World!"]
i = 0
str = ""
while i < len(list):
str += list[i] + " "
i += 1
print(str) #結果は同じ
forの方がコードが分かりやすいかと思います。
このようにforは「イテラブルの処理」に適した繰り返し処理です。
一方whileは「条件に合致する間繰り返し続ける処理」に適しており、無限ループなどはwhileで記述すべきでしょう。
[構文]
for 変数 in イテラブル:
# インデント開始(空白)
命令1
命令2
命令3
# インデント終了
また、イテラブルを使わずにforを使いたい場合はrange()を使うと簡単に繰り返し処理ができます。
for i in range(5):
print(i)
[出力結果]
0
1
2
3
4
range()は「与えられた数値から数値の連続を作成する」関数です。
今回は5を引数に渡したので、0〜4までの数値の連続を作成しているので、結果がこのようになっています。特に処理したいイテラブルはないが、繰り返し処理が必要な場合はrange()を使うと良いでしょう。
breakとcontinue
forでもwhileと同じようにbreakとcontinueが使えます。
実際に使ってみましょう。まずはbreakからです。
list = [1, 2, 3, 4, "5", 6, True, 8]
sum = 0
for i in list:
if type(i) is int:
sum += i
else:
break
print(sum)
[出力結果]
10
リスト内の要素を先頭から足していき、int以外の要素に当たったらbreakで処理を抜けています。listの5番目の要素は文字列の5なので、5番目の要素の前までの数値が全て足され、10が結果として出力されています。
つぎにcontinueを見てみましょう。今のプログラムのbreakをcontinueに置き換えてみてください。
list = [1, 2, 3, 4, "5", 6, True, 8]
sum = 0
for i in list:
if type(i) is int:
sum += i
else:
continue
print(sum)
[出力結果]
24
今度は24が出力されました。
先ほどはbreakだったので5番目の要素で終わっていましたが、今回はcontinueなので「リストの中でint型の要素だけを抽出し、足し合わせる」処理に変わっています。
このように、forとbreak、continueを組み合わせると、イテラブル内の必要な要素のみにフォーカスして処理をすることが可能です。
forのネスト
最後にforのネストを見ていきましょう。
ネストとは「forの中にforを書く」ことです。
では例を見てみましょう。
for i in range(3):
print("外-" + str(i + 1) + "回")
for j in range(3):
print(" 内-" + str(j + 1) + "回")
[出力結果]
外-1回
内-1回
内-2回
内-3回
外-2回
内-1回
内-2回
内-3回
外-3回
内-1回
内-2回
内-3回
これは「3回繰り返し処理をするforを3回繰り返す」プログラムです。
一見複雑ですが、一つずつ処理を追っていけば、実はそこまで難しくはありません。まずは外側のforが実行され、「外-1回」が出力されます。次に内側のforが実行されます。内側のforは単純に3回print()を呼び出すので、「内-1回〜内-3回」を出力します。終わったら外側のforに移動します。変数iには次の数値が代入されているので「外-2回」が出力されます。
後は同じ処理を繰り返しているだけです。内側のforが3回実行されたら繰り返しを抜け出し、処理が終わります。
forのネストはよく使われますが、処理の流れが追いにくいので、書く場合はどのように処理が流れるのか注視する必要があります。
ループカウンタも同時に取得する - enumerate()
リストなどのイテラブルをループする際、ループカウンタも同時に取得したい場合はenumerate()を使います。
enumerate()にイテラブルを渡すことで、ループカウンタとイテラブルの要素の2つを返却してくれます。
list = ["Hello", "Python", "World!"]
for i, s in enumerate(list) :
print("{}, {}".format(i, s))
[出力結果]
0, Hello
1, Python
2, World!
また、enumerate()は第二引数に数値を指定することで、どの数値からループカウンタを返却するかを指定できます。
for i, s in enumerate(list, 10) : #ループカウンタを10からスタート
[出力結果]
10, Hello
11, Python
12, World!
複数のリストの要素を同時取得する - zip()
複数のリストやタプルなどのイテラブルを同時にループしながら要素を取得したい場合はzip()を使います。
l_name = ["sato", "suzuki", "tanaka"]
l_score1 = [89, 61, 54]
l_score2 = [77, 91, 82]
for name, score1, score2 in zip(l_name, l_score1, l_score2):
print("{} \t {} \t {}".format(name, score1, score2))
[出力結果]
sato 89 77
suzuki 61 91
tanaka 54 82
上記の例では3つのリストの要素を同時に取得しprint()で出力しています。
また、zip()の引数として指定したリストの中で、要素数が少ないリストが存在する場合、少ない方の要素数を基準にループします。
l_name = ["sato", "suzuki", "tanaka"]
l_score1 = [89, 61] #要素数が他のリストに比べ1つ足りない
l_score2 = [77, 91, 82]
for name, score1, score2 in zip(l_name, l_score1, l_score2):
print("{} \t {} \t {}".format(name, score1, score2))
[出力結果]
sato 89 77
suzuki 61 91
l_score1の要素が2つしかないので、他2つのリストの要素の内容が削られて出力されました。
もし足りない分の要素を任意の値で埋めたい場合はitertoolsモジュールのzip_longest()を使います。
from itertools import zip_longest
l_name = ["sato", "suzuki", "tanaka"]
l_score1 = [89, 61]
l_score2 = [77, 91, 82]
for name, score1, score2 in zip_longest(l_name, l_score1, l_score2, fillvalue=0): #fillvalueで任意の値を指定
print("{} \t {} \t {}".format(name, score1, score2))
[出力結果]
sato 89 77
suzuki 61 91
tanaka 0 82
tanakaさんのスコアが1つ足りない分を0に置き換えるために、fillvalueで0を指定しています。
fillvalueを指定しない場合はNoneになります。