10.1. Iterator About
Processes one element at a time
Does not remember previous element
Does not know next element
Can be used only once
Save memory (does not require more memory for processing large data)
Values are computed on demand
No need to store all values in memory
Typical usage: streams, processing larger than memory files or data
Functions (list, dict, tuple, frozenset, set, sum, all, any, etc) will evaluate generator instantly
- iterable
An object supporting iteration. To create iterable class must implement
Iterable
protocol, to has__iter__()
method.- iterator
An iterable object. To create iterator class must implement
Iterator
protocol, to has__iter__()
and__next__()
method.
10.1.1. Examples
reversed(sequence, /)
range(start=0, stop, step=1)
,count
enumerate(iterable, start=0)
zip(*iterables, strict=False)
,zip_longest
map(func, iterables*)
,starmap
filter(func, iterable)
chain(*iterables)
permutations(iterable, r=None)
product(*iterables, repeat=1)
cycle(iterable, /)
10.1.2. Plain Function
Plain function returns plain object
>>> def run():
... return 1
>>> type(run)
<class 'function'>
>>> type(run())
<class 'int'>
10.1.3. Generator Function
Generator function returns generator object
>>> def run():
... yield 1
>>> type(run)
<class 'function'>
>>> type(run())
<class 'generator'>
10.1.4. Yield vs. Return
After
return
function stopsAfter
yield
function pauses
We want to return three values from a function. We cannot use return
keyword three times, because function will stop being executed after
encountering first return
:
>>> def run():
... return 1
... return 2 # this will never be executed
... return 3 # this will never be executed
In order to do so, we can return one list of three values:
>>> def run():
... return [1, 2, 3]
Or we can yield each value:
>>> def run():
... yield 1
... yield 2
... yield 3
10.1.5. Lazy Evaluation
After
yield
function pausesCalling
next()
resumes function until nextyield
After last
yield
raisesStopIteration
>>> def run():
... yield 1
... yield 2
... yield 3
>>>
>>>
>>> result = run()
>>>
>>> next(result)
1
>>>
>>> next(result)
2
>>>
>>> next(result)
3
>>>
>>> next(result)
Traceback (most recent call last):
StopIteration
10.1.6. Instant Evaluation
Using
list()
will evaluate generator instantlyFunctions (
list
,tuple
,set
,dict
,sum
,min
,max
,all
,any
, etc) will evaluate generator instantly
>>> def run():
... yield 1
... yield 2
... yield 3
>>>
>>>
>>> result = run()
>>> list(result)
[1, 2, 3]
10.1.7. Iterate
>>> def run():
... yield 1
... yield 2
... yield 3
>>>
>>>
>>> for result in run():
... print(result)
1
2
3