LoginSignup
4
0

More than 5 years have passed since last update.

今まで勘違いしていたPythonのrange()

Last updated at Posted at 2019-03-05

range()

恥ずかしながら、今までrange()はリストを返すものだと勘違いしていました。

Python 2系

私が開発環境として準備したPython 2.7でrange()を試してみました。以下にそれを示します。

>>> a = range(0, 10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> type(a)
<type 'list'>

このようにPython 2系では、range()はlist型を返してきます。これがPython 3系でも同様に成り立っていると勘違いしていました。

Python 3系

では私がメインの開発環境として使用しているPython 3.7で同様のことを実行してみましょう。

>>> a = range(0, 10)
>>> a
range(0, 10)
>>> type(a)
<class 'range'>

このようにPython 3系ではrange()はrange型という、イテラブルなオブジェクトを返します。[0, 1, ..., 9]のような戻り値をどうしても取り出したい場合は、forループで取り出すか、リストなどのシーケンスに変換する必要があります。

>>> list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> tuple(a)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

勘違いの原因: len()

len()は引数にリスト型などのシーケンスをとると思っていたのです。ところが

>>> a = range(0, 10)
>>> len(a)
10

のようにrangeオブジェクトの長さも平気で計算して返してきます。しかし、よくよく調べてみれば(というよりもすでに私自身、意識せずとも使っていたのですが)、len()は様々なオブジェクトのサイズを返すことができる万能な関数だったのです。

当たり前のようにforループで使っていましたが、まさかこんな落とし穴があったとは...まだまだPythonの奥深さを勉強していく必要がありそうです。

追記: rangeオブジェクトの要素へのアクセス

なんとこのrangeオブジェクトは要素へのアクセスも可能でした。これも私の勘違いに拍車をかけた要因でした。

>>> a = range(0, 5)
>>> a[0]
0

ただし、スライスを行うと以下のようにrangeオブジェクトのまま返ってきます。

>>> a[1:3]
range(1, 3)
4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0