note.nkmk.me

Pythonのrange関数の使い方

Date: 2018-12-25 / tags: Python

Pythonで連番や等差数列を生成してfor文で使ったり、それらのリストを取得するには、range()を使う。

ここでは以下の内容について説明する。

  • Python2とPython3でのrange()の違い
    • Python2のrange()xrange()
    • Python3のrange()
  • 0から任意の値までの連番: range(stop)
  • 任意の範囲の連番: range(start, stop)
  • 任意の範囲、増分の等差数列: range(start, stop, step)
  • 逆順のrange()
  • 浮動小数点数floatの場合

for文による繰り返し処理全般については以下の記事を参照。

スポンサーリンク

Python2とPython3でのrange()の違い

Python2系とPython3系でrange()の扱いが異なる。Python2の古いコードをそのままPython3で実行するとエラーになるので注意。

Python2のrange()とxrange()

Python2にはrange()xrange()という2つの関数がある。

range()はリストを返し、xrange()xrange型のオブジェクトを返す。

print(range(3))
# [0, 1, 2]

print(type(range(3)))
# <type 'list'>

print(xrange(3))
# xrange(3)

print(type(xrange(3)))
# <type 'xrange'>

xrange()は値をすべて保持せず必要なときに生成するため、上の例のようにそのままprint()で出力しても中身の数値は表示されない。イテラブル(反復可能)オブジェクトなのでfor文だとOK。

for i in xrange(3):
    print(i)
# 0
# 1
# 2

Python3のrange()

Python3にはxrange()はなくrange()のみ。xrange()は定義されていないためエラーとなる。

# print(xrange(3))
# NameError: name 'xrange' is not defined

Python3のrange()はPython2のxrange()に相当しrange型のオブジェクトを返す。Python2のコードをPython3で実行したい場合、xrange()に関するエラーについてはrange()に変更すればOK。

print(range(3))
# range(0, 3)

print(type(range(3)))
# <class 'range'>

for i in range(3):
    print(i)
# 0
# 1
# 2

Python2のrange()のようにリストを生成したい場合はlist()を使う。

print(list(range(3)))
# [0, 1, 2]

以降のサンプルコードではlist()でリスト化して出力する。これはあくまでも説明のためで、for文で使う場合はlist()は不要。

0から任意の値までの連番: range(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始まりで1ずつ増加する連番なので、負の値を指定すると空になる。

print(list(range(-3)))
# []

任意の範囲の連番: range(start, 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)

range(startm stop, step)のように引数に整数を3つ指定すると、start ≦ i < stopstepずつ増加する等差数列が生成される。

引数stepに負の値を指定すると減少していく。この場合は、start ≦ stopでないと空となる。

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を使える環境であれば、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組み込みのリスト型との変換などは以下の記事を参照。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事