Pythonのrange関数の使い方
Pythonで連番を生成してfor文で使ったりそのリストを取得するにはrange()
を使う。範囲やステップの指定も可能で、0からではなく1から、飛ばし飛ばし、逆順の連番も生成できる。
for文による繰り返し処理全般については以下の記事を参照。
range()とrange型
Python3のrange()
はrange
型オブジェクトを生成する。本記事のタイトルでは便宜上「range関数」としているが、関数というよりrange
型のコンストラクタといったほうが正確。
range
型オブジェクトは値を必要なときに生成するため、print()
で出力しても中身は表示されない。イテラブル(反復可能)オブジェクトなのでfor文ではそのまま使える。
print(range(3))
# range(0, 3)
print(type(range(3)))
# <class 'range'>
for i in range(3):
print(i)
# 0
# 1
# 2
リストを生成したい場合はlist()
を使う。
print(list(range(3)))
# [0, 1, 2]
以降のサンプルコードではlist()
でリスト化して出力している。これはあくまでも説明のためで、for文で使う場合はlist()
は不要。
なお、Python2にはrange()
とxrange()
があり、Python3とrange()
の扱いが異なる。最後に説明する。
range()の範囲指定
range()
に指定する引数の数によって、指定できる範囲とステップが変わる。
range(stop): 0 ≦ i < stop
range(stop)
のように引数に整数を1つ指定すると、0 ≦ i < stop
の連番が生成される。stop
の値は結果に含まれない。
print(list(range(3)))
# [0, 1, 2]
print(list(range(10)))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0始まりでstop
まで1ずつ増加する連番なので、stop
に負の値を指定すると空になる。
print(list(range(-3)))
# []
range(start, stop): start ≦ i < stop
range(start, stop)
のように引数に整数を2つ指定すると、start ≦ i < stop
の連番が生成される。start
の値は結果に含まれるがstop
の値は含まれない。
1ずつ増加する連番なので、stop ≦ start
のときは空となる。
print(list(range(3, 10)))
# [3, 4, 5, 6, 7, 8, 9]
print(list(range(10, 3)))
# []
print(list(range(-3, 3)))
# [-3, -2, -1, 0, 1, 2]
print(list(range(3, -3)))
# []
start
を0としたrange(0, stop)
はrange(stop)
と等価。
print(range(0, 3) == range(3))
# True
range(start, stop, step): start ≦ i < stop(stepずつ)
range(start, stop, step)
のように引数に整数を3つ指定すると、start ≦ i < stop
でstep
ずつ増加する等差数列が生成される。step
に負の値を指定すると減少していく。
print(list(range(3, 10, 2)))
# [3, 5, 7, 9]
print(list(range(10, 3, 2)))
# []
print(list(range(10, 3, -2)))
# [10, 8, 6, 4]
print(list(range(3, 10, -2)))
# []
step
を1としたrange(start, stop, 1)
はrange(start, stop)
と等価。
print(range(3, 10, 1) == range(3, 10))
# True
さらにstart
を0としたrange(0, stop, 1)
はrange(0, stop)
およびrange(stop)
と等価。
print(range(0, 10, 1) == range(0, 10) == range(10))
# True
逆順(降順)のrange()
第三引数step
に負の値を指定して任意のrange()
の逆順(降順)を生成することが可能だが、start
, stop
と合わせて適切な値を指定する必要があるため面倒。
print(list(range(3, 10, 2)))
# [3, 5, 7, 9]
print(list(range(9, 2, -2)))
# [9, 7, 5, 3]
組み込み関数reversed()
を使うと結果をそのまま逆順にできる。何も考えなくていいので楽。
print(list(reversed(range(3, 10, 2))))
# [9, 7, 5, 3]
reversed()
の場合も、for文で使う場合はlist()
は不要。
for i in reversed(range(3, 10, 2)):
print(i)
# 9
# 7
# 5
# 3
浮動小数点数floatの連番・等差数列
これまでの例のように、range()
の引数に指定できるのは整数int
のみ。浮動小数点数float
を指定するとエラーになる。
# print(list(range(0.3, 1.0, 0.2)))
# TypeError: 'float' object cannot be interpreted as an integer
リスト内包表記
浮動小数点数の等差数列を生成したい場合はリスト内包表記を使う。
- 関連記事: Pythonリスト内包表記の使い方
print([i / 10 for i in range(3, 10, 2)])
# [0.3, 0.5, 0.7, 0.9]
浮動小数点数との積を使うと誤差が生じる場合がある。これはround()
で丸められる。
print([i * 0.1 for i in range(3, 10, 2)])
# [0.30000000000000004, 0.5, 0.7000000000000001, 0.9]
print([round(i * 0.1, 1) for i in range(3, 10, 2)])
# [0.3, 0.5, 0.7, 0.9]
NumPy
NumPyを使える環境であれば、np.arange()
を使うほうが簡単。np.arange()
の引数の指定はrange()
と同じで、浮動小数点数float
を指定可能。
import numpy as np
print(np.arange(3))
# [0 1 2]
print(np.arange(3, 10))
# [3 4 5 6 7 8 9]
print(np.arange(3, 10, 2))
# [3 5 7 9]
print(np.arange(0.3, 1.0, 0.2))
# [0.3 0.5 0.7 0.9]
np.arange()
についての詳細や、NumPy配列ndarray
とPython組み込みのリスト型との変換などは以下の記事を参照。
Python2におけるrange()とxrange()
Python3にはrange()
しかないが、Python2にはrange()
とxrange()
という2つの関数がある。Python2とPython3でrange()
の扱いが異なり、Python2の古いコードをそのままPython3で実行するとエラーになる場合があるので注意。
Python2では、range()
はリストを返し、xrange()
はxrange
型のオブジェクトを返す。以下はPython2で実行した結果。
print(range(3))
# [0, 1, 2]
print(type(range(3)))
# <type 'list'>
print(xrange(3))
# xrange(3)
print(type(xrange(3)))
# <type 'xrange'>
Python2のxrange()
とxrange
型はPython3のrange()
とrange
型に相当する。
Python2のコードをPython3で実行する場合、xrange()
はそのままrange()
に変更すればよい。Python2のrange()
はリストを返すので、Python3ではlist(range())
に相当する。for
文で使われている場合はlist()
は必要ないが、リストとして使われている場合はlist()
が必要。