公開日:2019/9/19
更新日:2019/9/19
キーワード:Python for文 基本構文
文字数:4700(読み終わるまでおよそ8分)
この記事でわかること
- for文とは
- for文と関連する基本構文
はじめに
プログラミングの基本は「条件分岐」と「繰り返し」の制御構造で、データサイエンスの世界でよく使われるプログラミング言語であるPythonにおいても、例外ではありません。
Pythonでは、繰り返しにはfor文または while文を、条件分岐にはif文を使います。
プログラミングの初心者にとっては、for文が難しいと思いますので、今回はfor文および関連する基本的な構文を見ていきます。
1. 制御構造における基本構文
1) for文とは
for文は、指定した回数だけ処理を繰り返したり、タプルやリストから値を順番に取り出したりする、ループ処理で使う構文です。
Pythonでは他のプログラム言語と違い、インデント(字下げ)を使ってfor文のブロックを解釈するので、注意が必要です。
本稿では、インデントは半角4文字で設定することとします。
<例文1-1>
country = ["Japan", "China", "US", "India"]
for name in country:
print(name)
Japan
China
US
India
このコードでは、リストcountryに入っている国を、順番に取り出しています。
この機能を使って、指定回数だけ繰り返し処理を行うコードに活用します。ここで問題になるのが、処理を繰り返す回数をどう指定するかですが、range関数を使うことで実現できます。
n回処理を繰り返すには、次の書式のようになります。
for i in range(n): #インデントの開始(半角4文字下げ) ステートメント1 ステートメント2 ステートメント3 #インデントの終了(for文の終了) |
この流れを図にすると、次のように表せます(図1)。
変数iには、繰り返しごとに0, 1, 2, …, n-1の数値が入ります。0からn回繰り返すので、最後の値がn-1になることに注意が必要です。
実際のコードの例を、例文1-2に示します。
<例文1-2>
for i in range(10):
print(i)
0
1
2
3
4
5
6
7
8
9
変数iの値を出力するprint(i)を10回繰り返していることが、分かります。
2) range関数について
さて、for文を作成する際、処理の繰り返し数を指定するのに、range関数を用いました(例文1-2)。
ここでは、range関数について詳しく見ていきます。
他のプログラミング言語を学んだ方であれば、例文1-2の変数iは繰り返し数を数えるカウンタと思われるかと思いますが、Pythonでは少し考え方が違っており、range(10)が作った0~9の連続した数値から値を一つずつ取り出して、iに代入しています。
range関数は、連続した数字のオブジェクトを作るための関数で、次のような書式を持っています。
range(開始値,終了値,ステップ) |
開始値を省略すると0、ステップを省略すると1になります。
従って、先ほどfor文で用いたrange(10)を省略しないで書くと、range(0, 10, 1)ということになります。
例文1-2のrange(10)をrange(6,10)とすれば、6~9の値が出力されます(例文2-1)。出力される値は、6~10ではないことに注意してください。
<例文2-1>
for i in range(6, 10):
print(i)
6
7
8
9
range関数のステップを変えると、1個飛ばし(例文2-2)や逆順(例文2-3)の取り出しが可能となります。
<例文2-2>
for i in range(0, 10, 2):
print(i)
0
2
4
6
8
<例文2-3>
for i in range(10, 0, -1):
print(i)
10
9
8
7
6
5
4
3
2
1
ステップにマイナスの値を使って逆順に取り出す場合は、開始値と終了値を逆にすることを忘れないようにしてください。
3) for文とif文を使った複雑な条件分岐
以前、条件で処理を分岐させるときは、if文を使うことを述べました。
今回は、for文とif文を組合せて、少し複雑な条件分岐の作り方を見ていきます。
例文3-1は、0~9の数値の内、偶数ならそのままリストに追加し、奇数なら「奇数」という文字をリストに追加するコードです。
<例文3-1>
even_list = [] #空のリストを作る
for i in range(10):
if i % 2 == 0:
even_list.append(i) #2で割ったときの余りが0(つまり、偶数)なら、リストの最後に数値を追加する
else:
even_list.append("奇数") #奇数なら、「奇数」という文字をリストの最後に追加する
print(even_list)
[0, '奇数', 2, '奇数', 4, '奇数', 6, '奇数', 8, '奇数']
for文とif文を組み合わせることにより、for文の1回の繰り返しの中で、if-else文により条件の分岐処理を行い、それを規定の回数だけ繰り返す、といった処理が可能となります。
4) continueを用いた繰り返し処理のスキップ
for文の中でcontinueを実行することで、今の繰り返しを中断して、次の繰り返しに移る処理が可能となります。
continueを使ったfor文の流れを、図2に示します。
continueを使ったときのfor文の例を、例文4-1に示します。
数値と文字が混在したリストがあり、文字は飛ばして数値だけ足し算するコードです。
<例文4-1>
number = [2, 5.4, "a", 10, 1, "b", 20]
sum = 0
for num in number:
if not isinstance(num, (int, float)):
print(num, "数値ではありません")
continue
sum += num
print(num, "/", sum)
2 / 2
5.4 / 7.4
a 数値ではありません
10 / 17.4
1 / 18.4
b 数値ではありません
20 / 38.4
7つの数値または、文字を含むリストから順番に要素を取り出し、数値であれば数値と累積の合計値を示し、文字であれば、数値でないことを表示して、次の要素を取り出します。
文字列の”a”と”b”を取り出した後も、繰り返しを続けているのが分かります。
5) 複数のリストを組み合わせるzip関数
zip関数を使うと、for文で複数のリストを同時に扱うことができます。
例文5-1では、lnameとfnameのリストから順番に要素を取り出して、連結してfullnameを作っています。
lnameから取り出した要素はn1に、fnameから取り出した要素はn2に格納されます。リストの長さが異なる場合は、最も短いリストに合わせて処理は終了します。
<例文5-1>
lname = ["安倍", "山口", "枝野", "玉木", "松井"]
fname = ["晋三", "那津男", "幸男", "雄一郎", "一郎"]
fullname = []
for n1, n2 in zip(lname, fname):
fullname.append(n1+n2)
print(fullname)
['安倍晋三', '山口那津男', '枝野幸男', '玉木雄一郎', '松井一郎']
6) enumerate関数でリストの要素とカウンタの値を取得
enumerate関数を用いることで、for文のループカウンタの値を、リストから取り出した要素と合わせて、変数に取り出すことができます。
例文6-1では、iにカウンタの値が入り、nameにlistから取り出した要素が格納されます。カウンタの値は指定しなければ0からですが、例文のように開始値を指定することもできます。
<例文6-1>
list = ["安倍", "山口", "枝野", "玉木", "松井"]
for i, name in enumerate(list, 1):
print(f"{i}: {name}さん")
1: 安倍さん
2: 山口さん
3: 枝野さん
4: 玉木さん
5: 松井さん
7) reverse関数でリストの要素を逆順で取得
リストの要素を逆順に取り出したい場合、リストの要素をreverse関数で逆順に並べ替えてから、先頭から順番に取り出す方法があります(例文7-1)。
リストに対してreverse関数を用いると、新しいリストを作るのではなく、元のリストの値を並び変えてしまうので注意してください。
元のリストはそのままにして、要素を逆順に取り出したい場合は例文7-2のように書けば問題ありません。
<例文7-1>
list = ["安倍", "山口", "枝野", "玉木", "松井"]
list.reverse()
for i in list:
print(f"{i}さん")
松井さん
玉木さん
枝野さん
山口さん
安倍さん
<例文7-2>
list = ["安倍", "山口", "枝野", "玉木", "松井"]
for i in list[::-1]:
print(f"{i}さん")
print(list) #元のリストを確認
松井さん
玉木さん
枝野さん
山口さん
安倍さん
['安倍', '山口', '枝野', '玉木', '松井']
8) リスト内包表記
リスト内包表記は、他のプログラミング言語では見られない、Pythonらしい記述方法の一つで、以下の書式で表せます。
[式 for 変数 in 要素] |
コードの可読性は低下してしまうものの、append関数を呼び出さないため、実行速度が速いというメリットがあります(例文8-1)。
<例文8-1>
num_list = [1, 2, 3, 4, 5]
num_double = [num*2 for num in num_list]
print(num_double)
[2, 4, 6, 8, 10]
例文8-1を、リスト内包表記を使わずに書くと、例文8-2のように書けます。
<例文8-2>
num_list = [1, 2, 3, 4, 5]
num_double = []
for num in num_list:
num_double.append(num*2)
print(num_double)
[2, 4, 6, 8, 10]
内包表記には条件式を入れることもでき、例えば例文3-1をリスト内包表記を使って書くと、とてもシンプルに書けます(例文8-3)。
<例文8-3>
even_list = [i if i % 2 == 0 else "奇数" for i in range(10)]
print(even_list)
[0, '奇数', 2, '奇数', 4, '奇数', 6, '奇数', 8, '奇数']
内包表記は非常にシンプルにコードを書けますが、初心者には分かりにくい表記なので、Pythonに慣れないうちは、内包表記を使わないコードを書くとよいと思います。
2. おわりに
今回は、Pythonの構文の中でも初心者がつまづきやすい、for文および関連する基本構文について述べました。
データ解析の際は、条件に合うデータのみデータベースから取り出すというように、条件分岐と繰り返しを使って、解析用のデータベースを作成したい場面が出てきます。
今回述べたfor文は、繰り返し処理の基本となる構文なので、しっかり理解しておいてください。
3. 参考サイト
リスト内包表記とif文を組み合わせるとき
https://qiita.com/kokorinosoba/items/eb72dac6b68fccbac04d
Python入門〜for文、if文を使って条件処理をする〜
https://to-kei.net/python/intro2/#forif