Pythonのrange関数の使い方

Modified: | Tags: Python

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 < stopstepずつ増加する等差数列が生成される。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

リスト内包表記

浮動小数点数の等差数列を生成したい場合はリスト内包表記を使う。

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()が必要。

関連カテゴリー

関連記事