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
Iterableprotocol, to has__iter__()method.- iteratorï
An iterable object. To create iterator class must implement
Iteratorprotocol, to has__iter__()and__next__()method.
10.1.1. Examplesï
reversed(sequence, /)range(start=0, stop, step=1),countenumerate(iterable, start=0)zip(*iterables, strict=False),zip_longestmap(func, iterables*),starmapfilter(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
returnfunction stopsAfter
yieldfunction 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
yieldfunction pausesCalling
next()resumes function until nextyieldAfter last
yieldraisesStopIteration
>>> 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
10.1.8. Rationaleï
>>> def a():
... return 1
... return 2
... return 3
>>> def b():
... return 1, 2, 3
>>> def c():
... return 1, 2, 3, 4, 5, ..., 1_000_000
>>> def d():
... yield 1
... yield 2
... yield 3
... yield 4
... yield 5
... ...
... yield 1_000_000
>>> def e():
... for x in range(1, 1_000_001):
... yield x
10.1.9. Assignmentsï
# %% About
# - Name: Iterator About Yield
# - Difficulty: easy
# - Lines: 4
# - Minutes: 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `run() -> Iterator[int]`
# 2. Function yields 1
# 3. Function yields 2
# 4. Function yields 3
# 5. Use `yield` keyword
# 6. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `run() -> Iterator[int]`
# 2. Funkcja jelduje 1
# 3. Funkcja jelduje 2
# 4. Funkcja jelduje 3
# 5. Użyj sÅowa kluczowego `yield`
# 6. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> result = run()
#
# >>> next(result)
# 1
#
# >>> next(result)
# 2
#
# >>> next(result)
# 3
#
# >>> next(result)
# Traceback (most recent call last):
# StopIteration
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert isfunction(run)
>>> result = run()
>>>
>>> next(result)
1
>>> next(result)
2
>>> next(result)
3
>>> next(result)
Traceback (most recent call last):
StopIteration
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable, Iterator
run: Callable[[], Iterator[int]]
# %% Data
# %% Result
def run():
...
# %% About
# - Name: Iterator About For-Yield
# - Difficulty: easy
# - Lines: 3
# - Minutes: 3
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `run() -> Iterator[int]`
# 2. Function yields 1
# 3. Function yields 2
# 4. Function yields 3
# 5. Use `yield` keyword
# 6. Use `for` loop
# 7. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `run() -> Iterator[int]`
# 2. Funkcja jelduje 1
# 3. Funkcja jelduje 2
# 4. Funkcja jelduje 3
# 5. Użyj sÅowa kluczowego `yield`
# 6. Użyj pÄtli `for`
# 7. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> result = run()
#
# >>> next(result)
# 1
#
# >>> next(result)
# 2
#
# >>> next(result)
# 3
#
# >>> next(result)
# Traceback (most recent call last):
# StopIteration
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert isfunction(run)
>>> result = run()
>>>
>>> next(result)
1
>>> next(result)
2
>>> next(result)
3
>>> next(result)
Traceback (most recent call last):
StopIteration
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable, Iterator
run: Callable[[], Iterator[int]]
# %% Data
# %% Result
def run():
...
# %% About
# - Name: Iterator About Adult-List
# - Difficulty: easy
# - Lines: 6
# - Minutes: 3
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `adults(users) -> list[str]`
# 2. Function returns firstnames of adult users (age >= 18)
# 3. Do not use `yield` keyword
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `adults(users) -> list[str]`
# 2. Funkcja zwraca imiona (firstname) użytkowników peÅnoletnich (wiek >= 18)
# 3. Nie używaj sÅowa kluczowego `yield`
# 4. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> list(adults(users))
# ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert isfunction(adults)
>>> list(adults(users))
['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
adults: Callable[[list[tuple[str,str,int]]], list[str]]
# %% Data
DATA = [
('firstname', 'lastname', 'age'),
('Alice', 'Apricot', 30),
('Bob', 'Blackthorn', 31),
('Carol', 'Corn', 32),
('Dave', 'Durian', 33),
('Eve', 'Elderberry', 34),
('Mallory', 'Melon', 15),
]
header, *users = DATA
# %% Result
def adults(users):
...
# %% About
# - Name: Iterator About Adult-Iterator
# - Difficulty: easy
# - Lines: 4
# - Minutes: 3
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `adults(users) -> Iterator[int]`
# 2. Function returns firstnames of adult users (age >= 18)
# 3. Use `yield` keyword
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `adults(users) -> Iterator[int]`
# 2. Funkcja zwraca imiona (firstname) użytkowników peÅnoletnich (wiek >= 18)
# 3. Użyj sÅowa kluczowego `yield`
# 4. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> list(adults(users))
# ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert isfunction(adults)
>>> list(adults(users))
['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable, Iterator
adults: Callable[[list[tuple[str,str,int]]], Iterator[int]]
# %% Data
DATA = [
('firstname', 'lastname', 'age'),
('Alice', 'Apricot', 30),
('Bob', 'Blackthorn', 31),
('Carol', 'Corn', 32),
('Dave', 'Durian', 33),
('Eve', 'Elderberry', 34),
('Mallory', 'Melon', 15),
]
header, *users = DATA
# %% Result
def adults(users):
...