Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't range getting exhausted in Python-3?

If I do the following:

a = range(9)

for i in a:
    print(i)

# Must be exhausted by now
for i in a:
    print(i)

# It starts over!

Python's generators, after raising StopIteration, normally stops looping. How then is range producing this pattern - it restarts after every iteration.

like image 515
Renae Lider Avatar asked Dec 16 '14 09:12

Renae Lider


Video Answer


3 Answers

As has been stated by others, range is not a generator, but sequence type (like list) that makes it an iterable which is NOT the same as an iterator.

The differences between iterable, iterator and generator are subtle (at least for someone new to python).

  • An iterator provides a __next__ method and can be exhausted, thus raising StopIteration.
  • An iterable is a object that provides an iterator over its content. Whenever its __iter__ method is called it returns a NEW iterator object, thus you can (indirectly) iterate over it multiple times.
  • A generator is a function that returns an iterator, which of cause can be exhausted.

  • Also good to know is, that the for loop automaticly queries the iterator of any iterable. Which is why you can write for x in iterable: pass instead of for x in iterable.__iter__(): pass or for x in iter(iterable): pass.

All of that IS in the documentation, but IMHO somewhat difficult to find. The best starting point is probably the Glossary.

like image 118
PeterE Avatar answered Oct 22 '22 02:10

PeterE


range is a kind of immutable sequence type. Iterating it does not exhaust it.

>>> a = iter(range(9))  # explicitly convert to iterator
>>>
>>> for i in a:
...     print(i)
...
0
1
2
3
4
5
6
7
8
>>> for i in a:
...     print(i)
...
>>>
like image 34
falsetru Avatar answered Oct 22 '22 03:10

falsetru


range is not a generator, it's a sequence type, like strings or lists.

So

for i in range(4):

is no different than

for i in "abcd":
like image 43
fredtantini Avatar answered Oct 22 '22 01:10

fredtantini