range()がPython 3.3のジェネレーターである場合、範囲でnext()を呼び出せないのはなぜですか?


84

ウェブ上の誤った情報の犠牲になっているかもしれませんが、何かを誤解している可能性が高いと思います。私がこれまでに学んだことに基づいて、range()はジェネレーターであり、ジェネレーターはイテレーターとして使用できます。ただし、このコード:

myrange = range(10)
print(next(myrange))

私にこのエラーを与えます:

TypeError: 'range' object is not an iterator

ここで何が欠けていますか?これが0を出力し、の次の値に進むことを期待していましたmyrange。私はPythonを初めて使用するので、かなり基本的な質問についてお詫びしますが、他の場所で適切な説明を見つけることができませんでした。


2
イテレータとループで反復できるものの違いについては、stackoverflow.com / q / 13054057/395760を参照してforください。

1
ジェネレーターはイテレーターではなくイテレーターであると言うのは正しいでしょうか?
ジェフ

4
@Jeff Iterablesはiter、イテレータを取得するために使用できるオブジェクトです。イテレータは、を使用して反復できるオブジェクトですnext。ジェネレーターは、イテレーター(ジェネレーター関数とジェネレーター式)のカテゴリです。少なくとも...私が考えるものだという
オレグPrypin

回答:


109

rangeは不変の反復可能なオブジェクトのクラスです。それらの反復動作はlistsと比較できnextます。それらを直接呼び出すことはできません。を使用してイテレータを取得する必要がありますiter

いいえ、rangeジェネレータではありません。

「なぜ直接反復可能にしないのか」とお考えかもしれません。そうですね、rangesには、その方法では不可能ないくつかの便利なプロパティがあります。

  • それらは不変であるため、辞書のキーとして使用できます。
  • 彼らは持っているstartstopstep(Pythonの3.3以降)、属性、countおよびindex方法を、彼らはサポートinlenおよび__getitem__操作。
  • 同じことをrange複数回繰り返すことができます。

>>> myrange = range(1, 21, 2)
>>> myrange.start
1
>>> myrange.step
2
>>> myrange.index(17)
8
>>> myrange.index(18)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 18 is not in range
>>> it = iter(myrange)
>>> it
<range_iterator object at 0x7f504a9be960>
>>> next(it)
1
>>> next(it)
3
>>> next(it)
5

11
別の便利な機能rangeのオブジェクトは、彼らが持っているということです__contains__:値が範囲内にあるかどうかをテストするために使用することができる方法5 in range(10) => True
Kindall氏

答えてくれてありがとう。これは今では理にかなっています。答えを受け入れる前に明確にしておきたいのは、このページの3分の1ほど下にあるイタリック体のメモで、「Python 3ではrange()はジェネレーターです」と書かれています。これは単に間違っていますか?
ジェフ

3
@ジェフ厳密に言えば、はい、それは間違っています。ノートの作者は、おそらくPython 3rangeでは怠惰であることを意味していました(リストを返す関数であるPython 2と比較して)。
Oleh Prypin 2012年

6
また:range(0,10,3)[3]9 in range(0,10,3)。範囲はかなり怠惰なリストです。
Lennart Regebro 2012年

2
@ user3079275「直接反復可能」は誤った名称であり、実際には「イテレータ」を意味します。イテレータには内部状態があるため、定義上変更可能です。「Iterable」は、可変であるかどうかに関係なく、イテレータを生成できるオブジェクトです。可変オブジェクトでさえ、通常はそれ自体がイテレータではなく、再利用可能な方法でイテレータを生成します(たとえば、2つのイテレータを使用して、2つの異なる場所で同じリストを個別に反復できます)。
Oleh Prypin 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.