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.
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).
iterator
provides a __next__
method and can be exhausted, thus raising StopIteration
.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.
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)
...
>>>
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":
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With