【Python】for文とrange関数

Pythonにおけるfor文とrange関数について紹介します。



range関数による数列の生成

range関数は0, 1, 2, …,n – 1の数列(数値の並び式)を生成します。

range(n) 0以上n未満の数値を順番に列挙した数列を生成

注意したいのが数列の最後の数値がnではなくn – 1であるということです。

コード例


print(list(range(3)))

実行結果

[0, 1, 2]

上のコードではrange関数で生成した数列をリストに格納して表示しています。

また初めの数値が0であることも注意すべきです。

私たち人間は1から始めるのが基本ですが、コンピュータは0から始めるのが基本だからです。

実行例の場合は3を実引数として与えていますが、これは0から始まる3個の数列なので0,1,2の3つの数値が順に表示されています。

for文による繰り返し

繰り返しを行うための繰り返し文はwhile文以外にもfor文があります。

for 変数名 in 並び式: スイート

「並び式に含まれる値を変数に取り出してスイートを実行する」という作業をすべて取り出すまで繰り返す。

for文やwhile文などは繰り返しを継続するかどうかの判定をループ本体の実行前に行います。このような構造を前判定繰り返しといいます。

前判定繰り返しでは判定次第では一度も繰り返しが行われないことがあります。

なおその逆の後判定繰り返しにあたるdo~while文やrepeat~until文はPythonにはありません。

コード例


# 読み込んだ回数だけカウントアップ(カウントは0から)

n = int(input('カウント数 : '))

for i in range(n):
  print(f'{i}回目 = ', i)

実行結果

カウント数 : 3
0回目 =  0
1回目 =  1
2回目 =  2

上のコードでは以下のことを行っています。

range(3)により数列0,1,2が生成(最初に1回だけ行われる)。

変数iに0を取り出して、スイート(print関数を呼び出す文)を実行。

変数iに1を取り出して、スイート(print関数を呼び出す文)を実行。

変数iに2を取り出して、スイート(print関数を呼び出す文)を実行。



range関数によるa以上b未満step個おきの数列生成

上のコードではn未満の数列を生成しましたがこれは簡略化された表示形式です。本来は以下の形式です。

range(a, b, step) a以上b未満の数値をstep個おきに順番に列挙した数列を生成

最初のコードではbのみにしたものでaを省略した場合は0とみなされます。

stepを省略した場合は1とみなされます。

コード例


print(f'list(range(10)) = ', list(range(10)))
print(f'list(range(2, 10)) = ', list(range(2, 10)))
print(f'list(range(2, 10, 2)) = ', list(range(2, 10, 2)))
print(f'list(range(10, 2, -1)) = ', list(range(10, 2, -1)))

実行結果

list(range(10)) =  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list(range(2, 10)) =  [2, 3, 4, 5, 6, 7, 8, 9]
list(range(2, 10, 2)) =  [2, 4, 6, 8]
list(range(10, 2, -1)) =  [10, 9, 8, 7, 6, 5, 4, 3]

stepに負の数を与えると大きいほうから小さいほうへと表示する逆順の数列が得られます。

この場合はaからb – 1までの数列となりますので実引数が逆になることと値には注意してください。

for文による繰り返し(1からカウント)

0からカウントアップというのは人間にはわかりにくいので1からカウントアップに書き換えたコードは以下の通りです。

コード例


# 読み込んだ回数だけカウントアップ(カウントは1から)

n = int(input('カウント数 : '))

for i in range(1, n + 1):
  print(f'{i}回目 = ', i)

実行結果

カウント数 : 3
1回目 =  1
2回目 =  2
3回目 =  3

range関数の第1引数を1、第2引数をn + 1とすることで実現できます。

スイート内のprint関数内のiをi + 1にしても実現できますがたくさんあった場合はすべてをもれなく修正するのは大変なので上記のようにrange関数内を書き換えたほうが楽です。

for文のelse節

while文の末尾にelse節が置けたようにfor文の末尾にもelse節が置けます。

コード例


# 1~10までの乱数を5個表示

import random

for _ in range(5):
  r = random.randint(1, 10)
  if (r == 5):
    print('\n5が生成したので終了します。')
    break
  print(r, end=' ')
else:
  print('\n5個の乱数を生成しました。')

実行結果(1)

8 7 8 7 8
5個の乱数を生成しました。

実行結果(2)

6 10 7 6
5が生成したので終了します。

for文の繰り返しにより1から10までの乱数を生成します。

その過程で5が生成された場合for文の繰り返しをbreak文で強制的に終了します。

break文で終了された場合は5は表示されず「5が生成したので終了します。」と表示しelse節は実行されません。

5が一度も生成されず5個表示された場合はelse節が実行され「5個の乱数を生成しました。」と表示されます。