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. 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 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 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):
...