cs95
cs95

Reputation: 402423

Why does conversion of a range object to generator result in a `range_iterator` object?

This is not a duplicate of Why a range_iterator when a range is reversed? You'll know why if you take a look at it.

My question pertains to the distinction between a generator resulting from range versus any other iterator, and why that distinction is made:

In [500]: iter(range(5))
Out[500]: <range_iterator at 0x10987f810>

Whereas...

In [506]: (i for i in range(4))
Out[506]: <generator object <genexpr> at 0x10a025fc0>

So, why is this distinction made and what merit does it have?

Upvotes: 3

Views: 270

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95948

Simple, range is not an iterator:

In [32]: r = range(10)

In [33]: next(r)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-33-0b5056469c9c> in <module>()
----> 1 next(r)

TypeError: 'range' object is not an iterator

range is a sequence type, and like all other containers, iter returns a corresponding iterator object:

In [34]: iter(list())
Out[34]: <list_iterator at 0x112197cc0>

In [35]: iter(tuple())
Out[35]: <tuple_iterator at 0x112107be0>

In [36]: iter(dict())
Out[36]: <dict_keyiterator at 0x1142eef98>

Generally, containers are iterables, not iterators. They implement __iter__, whereas an iterator implements __iter__ and __next__.

Note, the terminology in your title is a bit off, and frankly, I think you are conflating generators, iterators, and iterables. iter(obj) doesn't return a generator, it returns an iterator object. A generator is a language construct that allows for succinctly writing iterators. The generator objects returned by a generator function are iterators:

In [37]: def mygen():
    ...:     yield 1
    ...:     yield 2
    ...:

In [38]: g = mygen()

In [39]: g
Out[39]: <generator object mygen at 0x1121778e0>

In [40]: next(g)
Out[40]: 1

In [41]: iter(g) is g
Out[41]: True

Finally, a generator expression is just an even handier way of writing generators!

In [44]: (i for i in range(10) if i % 2 == 0)
Out[44]: <generator object <genexpr> at 0x10de89990>

In [45]: next(_)
Out[45]: 0

Upvotes: 7

Related Questions