Search code examples
pythoniteratorrangeenumerate

Difference in iterating through range vs enumerate


next(range(2))

gives error,

TypeError: 'range' object is not an iterator

but,

next(iter(range(2)))

works, and gives the output 0

but,

next(enumerate('a'))

works, and gives the output

(0, 'a')

and,

next(iter(enumerate('a')))

also does the same.

shouldn't both work in a similar way, what is the reason for this difference?


Solution

  • A range object is an iterable that can be used many times. Each time you create an iterator for range,you get a new range_iterator object that starts from the beginning of the range and is unaffected by other iterators created on the same object.

    >>> r = range(2)
    >>> type(r)
    <class 'range'>
    >>> type(iter(r))
    <class 'range_iterator'>
    >>> iter(r) is r
    False
    

    A enumerate object is an iterator. It will iterate through the contained sequence one time. Any new iterators created on the enumeration are in fact the same iterator object and using one affects any other copies you may have.

    >>> e = enumerate('a')
    >>> type(e)
    <class 'enumerate'>
    >>> type(iter(e))
    <class 'enumerate'>
    >>> iter(e) is e
    True
    

    In short, enumerate is the same as range_iterator, not range.