第6回 繰り返し#


Open In Colab


この授業で学ぶこと#

プログラミングにおいて処理の流れを制御する方法は二つある。一つは第5回に学んだ条件分岐で、もう一つは繰り返しである。 今回は繰り返し処理を実現する構文であるfor文とwhile文について学ぶ。

for文#

複数の要素からなるデータがあるとき、すべての要素に対して同じような処理を行いたいときに用いられる構文がfor文である。

_images/for.png

Fig. 10 for文の書き方#

if文と同じく、for文もヘッダーとブロックからなる。ヘッダーに for 変数名 in イテラブルオブジェクト: と書くと「イテラブルオブジェクトの各要素を順番に取り出して変数に代入し、そのつどブロックを実行する」という意味になる。ここで、イテラブルオブジェクトとは「繰り返し処理できるオブジェクト」のことである。例えば、リストや文字列などがこれにあたる。名前の由来は「繰り返す」という意味をもつ英単語 “iterate” から来ている。

例として、0 から n-1 までの数字を順に出力するプログラムを書いてみよう。これはfor文を用いることで次のように実現できる。

n = 5
for i in range(n):
    print(i)

range() 関数はイテラブルオブジェクトを生成する関数であり、range(n) により生成されるオブジェクトは 0 から n-1 までの n 個の整数を順に生成する。 for i in range(n): という構文により、これらの整数が順に変数 i に代入され、代入される度にブロックのコードが実行される。

文字列やリストもイテラブルオブジェクトである。文字列の場合は1文字ずつ、リストの場合は1要素ずつ変数に代入される。

for c in "text":  # cはcharacterの頭文字
    print(c)
for v in [2, 3, 4, 5]:  # vはvalueの頭文字(他にi, x, elem, itemなどがよく使われる)
    print(v)

for文に用いる変数名は自由に決めてよいが、一般的に短くて分かりやすく、代入されるデータを端的に表すものが好まれる。例えば文字が代入される場合には、慣例として cchar が使われることが多い。最初はそれほど気にする必要はないが、変数名にも意図があることは知っておくと良いだろう。

練習1
リスト values が与えられるとき、リストの要素を前から順に print するコードを作成しなさい。

# valuesの一例
values = [2, 3, 4, 5]

# 以下にコードを作成し、以下の部分のみ提出する

練習2
正の整数 n が与えられるとき、1 から n までの数字を順に print するコードを作成しなさい。

# nの一例
n = 5

# 以下にコードを作成し、以下の部分のみ提出する

ブロックの抜け方#

ここで、if文やfor文などブロックを形成する全ての構文に共通する話として、ブロックの抜け方について説明する。

_images/block.png

Fig. 11 ブロックを抜けるタイミング#

上の図は、処理がブロックを抜ける(終了する)タイミングを表したものである。 ヘッダーと左端を揃えて何かしらの処理を書くと、そのタイミングでブロックを抜けたと判断される。いくつか例を見てみよう。

例1
前回のBMIの例ではブロックの中で print を実行していたが、代わりにブロックの中で変数にメッセージを代入し、ブロックの外で変数を print することもできる。print(message) はブロックの外にあるため、bmi の値によらず必ず実行される。

bmi = 20
if bmi < 18.5:
    message = "低体重"
elif bmi < 25:
    message = "普通体重"
else:
    message = "肥満"
print(message)

例2
数値からなるリストの要素の合計を求めるコードは次のように書ける。まず変数 total を0で初期化し、for 文の中でリストの要素を順に total に足し込んで合計を計算している。

data = [2, 3, 4, 5]
total = 0
for v in data:
    total += v
print(total)

上と同じプログラムを以下のように書くこともできる。まず len() 関数は、リストの要素数を返す関数である。例えば、data = [2, 3, 4, 5] の場合、len(data) は 4 を返す。 for i in range(len(data)): と書くと変数 i0 から len(data)-1 までの整数が順に代入されるため、これを使って data[i] とすれば data の全ての要素にアクセスすることができる。

data = [2, 3, 4, 5]
total = 0
for i in range(len(data)):
    total += data[i]
print(total)

練習3
数値からなるリスト data が与えられるとき、リストの要素の平均値を求めて print するコードを作成しなさい。余裕のある人は、上の例2を参考に2通りの方法でコードを作成してみなさい(ただし片方のみ提出しなさい)。

# dataの一例 (この例では 2 と出力するのが正しい)
data = [1, 2, 3]

# 以下にコードを作成し、以下の部分のみ提出する

while文#

for文と同様に、while文も繰り返し処理を行うための構文である。

_images/while.png

Fig. 12 while文の書き方#

while文では、条件式が真(True)である限り、ブロックの処理を何度でも繰り返す。条件式が初めて偽(False)になった瞬間に、繰り返しを終了する。したがって、条件式を適切に設定しないと無限ループに陥る可能性がある。また、初めから条件式が偽の場合は、ブロックは一度も実行されない。

例として、0 から n-1 までの数字を順に出力するプログラムは、while文を使うと以下のように書ける。

n = 5
i = 0
while i < n:
    print(i)
    i += 1

リストの要素の合計を求めるプログラムは、while文を使って次のように書くこともできる。 この例では、繰り返しの度にインデックスを表す変数 i の値を1つずつ増やし、i がリストのインデックスの範囲を超えたところで条件式が偽となるように設定している。 これにより変数 i0 から len(data)-1 までの整数が順に代入され、data[i] とすることで data の全ての要素にアクセスしている。

data = [2, 3, 4, 5]
total = 0
i = 0
while i < len(data):
    total += data[i]
    i += 1
print(total)

練習4
正の整数 n が与えられるとき、1 から n までの数字を順に print するコードを、while文を使って作成しなさい。

# nの一例
n = 5

# 以下にコードを作成し、以下の部分のみ提出する

練習5
正の整数 n が与えられるとき、1 から n までの数字を n から始めて逆順print するコードを作成しなさい。
ヒント: in から始めて1ずつ減らしていき、i が0より大きい間だけ繰り返すようにするとよい。

# n の一例 (この例では 3 2 1 と順に出力するのが正しい)
n = 3

# 以下にコードを作成し、以下の部分のみ提出する
i = n
while i > 0:
    pass  # ここに適切なコードを書く

pass

pass は「何もしない」ことを意味する文である。構文上何か書かないとエラーになるが、コードの作成は後回しにしたい箇所に書く。テキストでも何度か登場するが、コードを書くときに消してしまって問題ない。

練習6
リスト data が与えられるとき、リストの要素を後ろから順に print するコードを作成しなさい。

# data の一例 (この例では 5 3 1 と順に出力するのが正しい)
data = [1, 3, 5]

# 以下にコードを作成し、以下の部分のみ提出する