Pythonのrange関数について

2021.10.04

2021.10.04

Fabeee社員ブログ


どうも、FabeeeのPythonエンジニア、バターです。

Pythonでプログラミングをしているとついつい使ってしまうrange関数、当記事ではこのrange関数の基本的な使用方法をご紹介していきます。
(Python2系のxrange関数は取り扱いません)

当記事で扱うPythonのバージョン

Python: v3.9.0

今回紹介する内容

Pythonのrange関数とは?
stop だけ指定してrange関数を実行
start, stop を指定してrange関数を実行
step を指定してrange関数を実行
step に負の値を指定してrange関数を実行
Pythonのrange関数のすごいところ
range型のオブジェクトは比較できる

Pythonのrange関数とは?

指定した長さの連続した整数のリストを生成する関数です。
Pythonのforループにおいて、特定回数ループさせたい場合などに使います。
リストを使えば同じことをできますが、長い回数繰り返そうと思うと面倒くさいですよね。

for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
print(i)

>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 6
>>> 7
>>> 8
>>> 9
>>> 10

リストを生成する関数といいましたが、range関数の戻り値は配列ではなくrange型のオブジェクトです(iterableなので配列っぽくは扱えます)。
range関数の書式は次の通りです(引用: Python3.9 公式ドキュメント)。

class range(stop)
class range(start, stop[, step])

早速range関数を試していきましょう。

stop だけ指定してrange関数を実行

出力範囲: 0からstop – 1までの連番
start を省略した場合は0始まりです。
step を省略した場合は1が指定されたものとみなされます。

for i in range(10):
print(i)

>>> 0
>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 6
>>> 7
>>> 8
>>> 9

start, stopを指定してrange関数を実行

出力範囲: startからstop – 1までの連番
特定の数値から開始したい場合などは、range関数のstartを指定すると良いですね!

for i in range(1, 10):
print(i)

>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 6
>>> 7
>>> 8
>>> 9

stepを指定してrange関数を実行

出力範囲: startからstepずつ増加させてstop – 1まで
range関数のstepに2以上の値を指定すると、0からstepずつ増加する等差配列が得られます。

for i in range(0, 21, 2):
print(i)

>>> 0
>>> 2
>>> 4
>>> 6
>>> 8
>>> 10
>>> 12
>>> 14
>>> 16
>>> 18
>>> 20

stepに負の値を指定してrange関数を実行

出力範囲: startからstepずつ減少させてstop + 1まで
range関数のstepに負の値を指定すると逆順の結果を得られます

for i in range(10, 0, -1):
print(i)

>>> 10
>>> 9
>>> 8
>>> 7
>>> 6
>>> 5
>>> 4
>>> 3
>>> 2
>>> 1

stop >= startにすると、空の配列が返ってきます。

print(list(range(5, 5, -1)))
>>> []

stepに負の値を指定するのが嫌だ、という方はPythonの組み込み関数reversedをご使用ください。
この通り、stepに負の値を指定しなくても逆順の結果を得ることができます。

for i in reversed(range(0, 10)):
print(i)

>>> 9
>>> 8
>>> 7
>>> 6
>>> 5
>>> 4
>>> 3
>>> 2
>>> 1
>>> 0

Pythonのrange関数のすごいところ

Pythonのrange関数が返すrange型のオブジェクトにはある特徴があります。
それは、
「start, stopの範囲に関わらず一定量の小さなメモリを消費すること」
です。
この通り、start, stopをどんな値にしようがrange関数のメモリ消費量は一定です。

import sys

print(f'メモリ使用量: {sys.getsizeof(range(0, 5))} byte')
メモリ使用量: 48 byte
print(f'メモリ使用量: {sys.getsizeof(range(0, 10000))} byte')
メモリ使用量: 48 byte

range型のオブジェクトを配列にキャストした場合のメモリ消費量はどうなるでしょうか。
start: 0, stop: 5の小さな数値配列ですらメモリ消費量に2倍の差が出ています。
間違ってもrange関数の戻り値を配列にキャストするのはやめましょう(戒め)

import sys

print(f'メモリ使用量: {sys.getsizeof(list(range(0, 5)))} byte')
>>> メモリ使用量: 96 byte
print(f'メモリ使用量: {sys.getsizeof(list(range(0, 10000)))} byte')
>>> メモリ使用量: 80056 byte

ちなみにrange型のオブジェクトをPythonの組み込み関数reversedで逆順にした場合でも、戻り値はrange型のオブジェクトなので、メモリ消費量は一定のままです。

range型のオブジェクトは比較できる

Pythonのrange関数が生成するrange型のオブジェクトはシーケンスの抽象規定クラスを継承しているので、比較が可能です(使い所はわからない)。

例えば、range(0, 3, 2) と range(0, 4, 2)が生成するrangeオブジェクトが出力する内容は同じなので、比較結果はTrueになります。

for i in range(0, 3, 2):
print(i)

>>> 0
>>> 2
for i in range(0, 4, 2):
print(i)

>>> 0
>>> 2
print(range(0, 3, 2) == range(0, 4, 2))

>>> True

まとめ

いかがだったでしょうか、今回はPythonのrange関数を紹介しました。
range関数は特定回数の繰り返し処理をシンプルに記述でき、パフォーマンスにも優しいとても便利な関数です。
この記事を参考にrange関数の使い方や特徴を掴んでいただければ幸いです!

Pythonを活用したシステム開発ならFabeee株式会社にお任せください。お問い合わせはコチラ

Fabeee編集部

Fabeee編集部

こちらの記事はFabeee編集部が執筆しております。