If range() is a generator in Python 3.3, why can I not call next() on a range?

generator, iterator, python, python-3.x, typeerror

Solution

`range` is a class of immutable iterable objects. Their iteration behavior can be compared to `list`s: you can't call `next` directly on them; you have to get an iterator by using `iter`.

So no, `range` is not a generator.

You may be thinking, "why didn't they make it an iterator"? Well, `range`s have some useful properties that wouldn't be possible that way:

- They are immutable, so they can be used as dictionary keys.

- They have the `start`, `stop` and `step` attributes (since Python 3.3), `count` and `index` methods and they support `in`, `len` and `__getitem__` operations.

- You can iterate over the same `range` multiple times.

>>> 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

Problem

Perhaps I've fallen victim to misinformation on the web, but I think it's more likely just that I've misunderstood something. Based on what I've learned so far, range() is a generator, and generators can be used as iterators. However, this code: ``` myrange = range(10) print(next(myrange)) ``` gives me this error: ``` TypeError: 'range' object is not an iterator ``` What am I missing here? I was expecting this to print 0, and to advance to the next value in `myrange`. I'm new to Python, so please accept my apologies for the rather basic question, but I couldn't find a good explanation anywhere else.

Original source

Related problems