10.14. Iterator Starmap

  • Lazy evaluated

  • itertools.starmap(function, iterable)

10.14.1. SetUp

>>> from itertools import starmap

10.14.2. Recall

>>> def square(x):
...     return x ** 2
>>>
>>> data = [1, 2, 3, 4]

List comprehension:

>>> result = [square(x) for x in data]
>>> list(result)
[1, 4, 9, 16]

Map function:

>>> result = map(square, data)
>>> list(result)
[1, 4, 9, 16]

10.14.3. Problem

>>> def power(n, exp):
...     return n ** exp
>>>
>>>
>>> data = [(1,2), (2,10), (3,3), (4,2)]
>>>
>>> result = [power(x) for x in data]
Traceback (most recent call last):
TypeError: power() missing 1 required positional argument: 'exp'
>>>
>>> result = [power(*x) for x in data]
>>> list(result)
[1, 1024, 27, 16]

10.14.4. Solution

>>> from itertools import starmap
>>>
>>>
>>> def power(n, exp):
...     return n ** exp
>>>
>>>
>>> data = [(1,2), (2,10), (3,3), (4,2)]
>>>
>>> result = map(power, data)
>>> list(result)
Traceback (most recent call last):
TypeError: power() missing 1 required positional argument: 'exp'
>>>
>>> result = starmap(power, data)
>>> list(result)
[1, 1024, 27, 16]

10.14.5. Case Study

>>> from itertools import starmap
>>> from pprint import pprint
>>>
>>>
>>> class User:
...     def __init__(self, firstname, lastname, age):
...         self.firstname = firstname
...         self.lastname = lastname
...         self.age = age
...
...     def __repr__(self):
...         clsname = self.__class__.__name__
...         firstname = self.firstname
...         lastname = self.lastname
...         age = self.age
...         return f'{clsname}({firstname=}, {lastname=}, {age=})'
>>>
>>>
>>> DATA = [
...     ('firstname', 'lastname', 'age'),
...     ('Alice', 'Apricot', 30),
...     ('Bob', 'Blackthorn', 31),
...     ('Carol', 'Corn', 32),
...     ('Dave', 'Durian', 33),
...     ('Eve', 'Elderberry', 34),
...     ('Mallory', 'Melon', 15),
... ]
>>>
>>> header = DATA[0]
>>> rows = DATA[1:]
>>> result = [User(*row) for row in rows]
>>> pprint(list(result))
[User(firstname='Alice', lastname='Apricot', age=30),
 User(firstname='Bob', lastname='Blackthorn', age=31),
 User(firstname='Carol', lastname='Corn', age=32),
 User(firstname='Dave', lastname='Durian', age=33),
 User(firstname='Eve', lastname='Elderberry', age=34),
 User(firstname='Mallory', lastname='Melon', age=15)]
>>> result = starmap(User, rows)
>>> pprint(list(result))
[User(firstname='Alice', lastname='Apricot', age=30),
 User(firstname='Bob', lastname='Blackthorn', age=31),
 User(firstname='Carol', lastname='Corn', age=32),
 User(firstname='Dave', lastname='Durian', age=33),
 User(firstname='Eve', lastname='Elderberry', age=34),
 User(firstname='Mallory', lastname='Melon', age=15)]

10.14.6. Assignments

# %% About
# - Name: Iterator Starmap Args
# - Difficulty: easy
# - Lines: 1
# - 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. Use `starmap()` to create `list[User]` from `DATA`
# 2. Define variable `result` with `list[User]` objects
# 3. Run doctests - all must succeed

# %% Polish
# 1. Użyj `starmap()` do stworzenia `list[User]` z `DATA`
# 2. Zdefiniuj zmienną `result` z obiektami `list[User]`
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% Expected
# >>> result
# [User(firstname='Alice', lastname='Apricot', age=30),
#  User(firstname='Bob', lastname='Blackthorn', age=31),
#  User(firstname='Carol', lastname='Corn', age=32),
#  User(firstname='Dave', lastname='Durian', age=33),
#  User(firstname='Eve', lastname='Elderberry', age=34),
#  User(firstname='Mallory', lastname='Melon', age=15)]

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0

>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'

>>> assert 'result' in globals(), \
'Variable `result` is not defined; assign result of your program to it.'

>>> assert result is not Ellipsis, \
'Variable `result` has an invalid value; assign result of your program to it.'

>>> assert type(result) is starmap, \
'Variable `result` has an invalid type; expected: `starmap`.'

>>> result = list(result)
>>> assert all(type(x) is User for x in result), \
'Variable `result` has elements of an invalid type; all items should be: `User`.'

>>> from pprint import pprint
>>> pprint(result)  # doctest: +NORMALIZE_WHITESPACE
[User(firstname='Alice', lastname='Apricot', age=30),
 User(firstname='Bob', lastname='Blackthorn', age=31),
 User(firstname='Carol', lastname='Corn', age=32),
 User(firstname='Dave', lastname='Durian', age=33),
 User(firstname='Eve', lastname='Elderberry', age=34),
 User(firstname='Mallory', lastname='Melon', age=15)]
"""

# %% 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
from itertools import starmap

# %% Types
result: starmap

# %% Data
class User:
    def __init__(self, firstname, lastname, age):
        self.firstname = firstname
        self.lastname = lastname
        self.age = age

    def __repr__(self):
        clsname = self.__class__.__name__
        firstname = self.firstname
        lastname = self.lastname
        age = self.age
        return f'{clsname}({firstname=}, {lastname=}, {age=})'


DATA = [
    ('firstname', 'lastname', 'age'),
    ('Alice', 'Apricot', 30),
    ('Bob', 'Blackthorn', 31),
    ('Carol', 'Corn', 32),
    ('Dave', 'Durian', 33),
    ('Eve', 'Elderberry', 34),
    ('Mallory', 'Melon', 15),
]

# %% Result
result = ...