12.2. Generator Function
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
Uses around 10% more CPU than regular processing
Typical usage: streams, processing larger than memory files or data
Cannot use
len()as of generators don't have lengthPrevious element is overridden by current on
next()Functions (list, dict, tuple, frozenset, set, sum, all, any, etc) will evaluate generator instantly
12.2.1. Plain Function
Plain function returns plain object
>>> def run():
... return 1
>>> type(run)
<class 'function'>
>>> type(run())
<class 'int'>
12.2.2. Generator Function
Generator function returns generator object
>>> def run():
... yield 1
>>> type(run)
<class 'function'>
>>> type(run())
<class 'generator'>
12.2.3. Yield vs. Return
After
returnfunction stopsAfter
yieldfunction pauses
>>> def run():
... return 1
... return 2
>>> def run():
... yield 1
... yield 2
12.2.4. Lazy Evaluation
After
yieldfunction pausesCalling
next()resumes function until nextyieldAfter last
yieldraisesStopIteration
>>> def run():
... yield 1
... yield 2
>>> result = run()
>>> next(result)
1
>>> next(result)
2
>>> next(result)
Traceback (most recent call last):
StopIteration
12.2.5. 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
>>> result = run()
>>> tuple(result)
(1, 2)
12.2.6. Assignments
# %% About
# - Name: Generator Function Plain
# - Difficulty: easy
# - Lines: 2
# - Minutes: 1
# %% 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. Create plain function `myfunc()` that returns `1`
# 2. Run doctests - all must succeed
# %% Polish
# 1. Stwórz zwykłą funkcję `myfunc()`, która zwraca `1`
# 2. Uruchom doctesty - wszystkie muszą się powieść
# %% Expected
# >>> myfunc()
# 1
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from sys import getsizeof
>>> from inspect import isfunction, isgeneratorfunction, isgenerator
>>> isfunction(myfunc)
True
>>> isgeneratorfunction(myfunc)
False
>>> result = myfunc()
>>> isgenerator(result)
False
>>> result
1
"""
# %% 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
a: Callable[[], int]
# %% Data
# %% Result
# %% About
# - Name: Generator Function Generator
# - Difficulty: easy
# - Lines: 2
# - Minutes: 1
# %% 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. Create generator function `run()` that yields `1`
# 2. Run doctests - all must succeed
# %% Polish
# 1. Stwórz funkcję generatorową `run()`, która yielduje `1`
# 2. Uruchom doctesty - wszystkie muszą się powieść
# %% Expected
# >>> run()
# <generator object a at 0x...>
#
# >>> result = run()
# >>> next(result)
# 1
# >>> 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 sys import getsizeof
>>> from inspect import isfunction, isgeneratorfunction, isgenerator
>>> isfunction(run)
True
>>> isgeneratorfunction(run)
True
>>> result = run()
>>> isgenerator(result)
True
>>> result # doctest: +ELLIPSIS
<generator object run at 0x...>
>>> next(result)
1
>>> 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
run: Callable[[], int]
# %% Data
# %% Result
# %% 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():
...