Pythonの組み込み関数であるrangeについて解説します。for文で大活躍するrangeですが、意外と詰まる関数ではないでしょうか。公式のドキュメントについてはこちらをご参照下さい。
用法1 : range(stop)
>>> list(range(3))
[0, 1, 2]
stopとして受け付けるオブジェクトは、int型または__index__メソッドを持つものです。与えられたstepに基づき、0~(step-1)のiteratableオブジェクトを返します。
__index__メソッドに関して
__index__は特殊メソッドに該当し、特別な意味を持つメソッドになります。__index__はint型にcastされる時に、返却する値を定義するもので、このメソッドを持つオブジェクトはint型にcast可能になります。
例を挙げるとBoolean型が該当し、Trueであれば1、Falseであれば0が返却されます。
>>> True.__index__
<method-wrapper '__index__' of bool object at 0x10cfe5a90>
>>> int(True)
1
>>> int(False)
0
rangeに話を戻します。
__index__が定義されたTrueをstopのrangeの引数として与えると、int型にcastされ1として解釈され実行されます。なので、range(1)とrange(True)は同義になります。(整数値以外を与えるのは、見たことないですけどねw)
>>> list(range(1))
[0]
>>> list(range(True))
[0]
listにcastしている理由について
理由は非常に単純で、そのままだと表示しても意味わかないからです。実行してみると以下のようになります。
>>> range(3)
range(0, 3)
そのままですね。rangeの戻り値は正確にはrange型オブジェクトです。これを標準出力した際は、rangeオブジェクトとして文字列化されるので、この結果となります(__str__の説明までしているとマトリョーシカになってくるので省きます)。
解説としては、range関数を実行した時にどんな値が返ってくるかを見せたいので、中身の分かりやすいlistにcastしています。
用法2 : range(start, stop)
>>> list(range(3,6))
[3, 4, 5]
startが追加されたことによって、開始する数を定義することが可能です(そのまま)。返される値は、start~(stop-1)です。
range(stop)は、range(0, stop)と同義になります。
>>> list(range(3))
[0, 1, 2]
>>> list(range(0,3))
[0, 1, 2]
負数を与えた時の挙動
負数であっても、整数値であれば同様に動作します。
>>> list(range(-3,3))
[-3, -2, -1, 0, 1, 2]
>>> list(range(-6,-3))
[-6, -5, -4]
用法3 : range(start, stop, step)
>>> list(range(2,20,3))
[2, 5, 8, 11, 14, 17]
stepが追加されました。stepは言い換えると「n個目の値とn+1個目の値の差分」です。2, 5(2+step(3)), 8(2+step(3))…と続いて行きます。
range(start, stop)とrange(start, stop, 1)は同義です。
>>> list(range(3,6))
[3, 4, 5]
>>> list(range(3,6,1))
[3, 4, 5]
何に使うのかピンと来ない人は多いと思います。簡単なところで言うと、倍数を表現することが出来ます。例えば20以下の3の倍数を表現したければ以下のように使用します。
>>> lis(range(3,20,3))
[3, 6, 9, 12, 15, 18]
また、奇数を表現したい場合にも活用することが出来ます。
>>> list(range(1,20,2))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
stepに負数を与えた時の挙動
>>> list(range(10,-10,-3))
[10, 7, 4, 1, -2, -5, -8]
期待通りに逆走してくれます。この時、start>stopとしないと空になってしまうので注意が必要です。
コメント