13.2. Comprehension Types

13.2.1. List Comprehension

  • [x for x in ...]

  • list(x for x in ...)

Short syntax:

>>> [x for x in range(0,5)]
[0, 1, 2, 3, 4]

Long Syntax:

>>> list(x for x in range(0,5))
[0, 1, 2, 3, 4]

13.2.2. Set Comprehension

  • {x for x in ...}

  • set(x for x in ...)

  • Unique elements

  • Ordered by hash of elements

Short Syntax:

>>> {x for x in range(0, 5)}
{0, 1, 2, 3, 4}

Long Syntax:

>>> set(x for x in range(0, 5))
{0, 1, 2, 3, 4}

Set contains only unique elements, and are ordered by hash:

>>> DATA = ['a', 'b', 'c', 'a']
>>>
>>> {x for x in DATA}
{'b', 'a', 'c'}

13.2.3. Dict Comprehension

  • {x:x for x in ...}

  • dict((x,x) for x in ...)

Short syntax:

>>> {x:None for x in range(0,5)}
{0: None, 1: None, 2: None, 3: None, 4: None}

Long syntax:

>>> dict((x,None) for x in range(0,5))
{0: None, 1: None, 2: None, 3: None, 4: None}

Example:

>>> {x:x+10 for x in range(0,5)}
{0: 10, 1: 11, 2: 12, 3: 13, 4: 14}

Remember that in dict duplicating items are overridden by the latter:

>>> data = {
...     'username': 'alice',
...     'username': 'bob',
... }
>>>
>>> data
{'username': 'bob'}

While generating dict with unique keys, there are no collisions:

>>> {x:None for x in range(0,5)}
{0: None, 1: None, 2: None, 3: None, 4: None}

Although when generating dict with constant key, it will be overridden by the last one:

>>> {None:x for x in range(0,5)}
{None: 4}

13.2.4. Tuple Comprehension

  • There is no short syntax for Tuple Comprehension

  • Round brackets will create Generator Expression

Short syntax:

>>> (x for x in range(0,5))
<generator object <genexpr> at 0x...>

Long syntax:

>>> tuple(x for x in range(0,5))
(0, 1, 2, 3, 4)

Example:

>>> data = (x for x in range(0,5))
>>>
>>> for result in data:
...     print(result)
...
0
1
2
3
4

13.2.5. Case Study

>>> data = [x for x in range(0,5)]          # list comprehension
>>> data = (x for x in range(0,5))          # generator expression
>>> data = {x for x in range(0,5)}          # set comprehension
>>> data = {x:x for x in range(0,5)}        # dict comprehension
>>> data = list(x for x in range(0,5))
>>> data = tuple(x for x in range(0,5))
>>> data = set(x for x in range(0,5))
>>> data = dict((x,x) for x in range(0,5))
>>> data = all(x for x in range(0,5))
>>> data = any(x for x in range(0,5))
>>> data = bool(x for x in range(0,5))
>>> data = sum(x for x in range(0,5))
>>> data = min(x for x in range(0,5))
>>> data = max(x for x in range(0,5))
>>> data = hash(x for x in range(0,5))
>>> data = callable(x for x in range(0,5))
>>> data = len(x for x in range(0,5))
Traceback (most recent call last):
TypeError: object of type 'generator' has no len()

13.2.6. Use Case - 1

  • Sum

>>> sum(x for x in range(0,5))
10

13.2.7. Use Case - 2

  • Reverse dict - swap keys with values

>>> DATA = {
...     'alice': 'secret',
...     'bob': 'qwerty',
...     'carol': '123456',
... }
>>>
>>> result = {v:k for k,v in DATA.items()}
>>>
>>> result
{'secret': 'alice',
 'qwerty': 'bob',
 '123456': 'carol'}

13.2.8. Use Case - 3

  • Reverse dict - swap keys with values

  • Dict Reversal Collision

Value collision while reversing dict (note that both b and c has value 2)

>>> DATA = {
...     'alice': 'secret',
...     'bob': 'secret',
...     'carol': '123456',
... }
>>>
>>> result = {v:k for k,v in DATA.items()}
>>>
>>> result
{'secret': 'bob',
 '123456': 'carol'}

13.2.9. Use Case - 4

  • Even or Odd

>>> DATA = [1, 2, 3, 4]
>>> result = {}
>>>
>>> for x in DATA:
...     is_even = (x % 2 == 0)
...     result.update({x: is_even})
>>>
>>> print(result)
{1: False, 2: True, 3: False, 4: True}
>>> DATA = [1, 2, 3, 4]
>>>
>>> {x:(x%2==0) for x in DATA}
{1: False, 2: True, 3: False, 4: True}

13.2.10. Assignments

# %% About
# - Name: Comprehension Types Dict
# - 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. Define `result: dict` with:
#    - `key: int` integer from 0 (inclusive) to 5 (exclusive)
#    - `value: int` value for key squared (raised to the power of 2)
# 2. Non-functional requirements:
#    - Use list comprehension
#    - Use `range()` function
#    - Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result: dict` z:
#    - `klucz: int` liczba całkowita od 0 (włącznie) do 5 (rozłącznie)
#    - `wartość: int` wartość dla klucza podniesiona do kwadratu
# 2. Non-functional requirements:
#    - Użyj list comprehension
#    - Użyj funkcji `range()`
#    - Uruchom doctesty - wszystkie muszą się powieść

# %% Example
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# %% Hints
# - `[... for ... in ...]`
# - `range(start,stop)`
# - `start is inclusive`
# - `stop is exclusive`

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert type(result) is dict, \
'Result should be a dict'
>>> assert all(type(x) is int for x in result), \
'Result should be a list of int'

>>> result
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result: dict[int,int]

# %% Data

# %% Result
result = ...

# %% About
# - Name: Comprehension Types Swap
# - 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. Reverse dict (swap keys and values)
# 2. Run doctests - all must succeed

# %% Polish
# 1. Odwróć dict (zamień klucze z wartościami)
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Example
# {'virginica': 0,
#  'setosa': 1,
#  'versicolor': 2}

# %% Hints
# - `dict.items()`

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is dict, \
'Variable `result` has invalid type, should be dict'

>>> assert all(type(x) is str for x in result.keys())
>>> assert all(type(x) is int for x in result.values())
>>> assert len(result.keys()) == 3

>>> assert 'virginica' in result.keys()
>>> assert 'setosa' in result.keys()
>>> assert 'versicolor' in result.keys()

>>> assert 0 in result.values()
>>> assert 1 in result.values()
>>> assert 2 in result.values()

>>> from pprint import pprint
>>> pprint(result, width=20, sort_dicts=False)
{'virginica': 0,
 'setosa': 1,
 'versicolor': 2}
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result: dict[str,int]

# %% Data
DATA = {
    0: 'virginica',
    1: 'setosa',
    2: 'versicolor',
}

# %% Result
result = ...

# %% About
# - Name: Comprehension Types Months
# - 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. Convert `DATA` into `result: dict`:
#    - Keys: month number
#    - Values: month name
# 2. Use dict comprehension
# 3. Run doctests - all must succeed

# %% Polish
# 1. Przekonwertuj `DATA` w `result: dict`:
#    - klucz: numer miesiąca
#    - wartość: nazwa miesiąca
# 2. Użyj dict comprehension
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% Example
# {1: 'January',
#  2: 'February',
#  3: 'March',
#  ...
#  11: 'November',
#  12: 'December'}

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

>>> type(result)
<class 'dict'>
>>> 0 not in result
True
>>> 13 not in result
True
>>> result[1] == 'January'
True

>>> assert all(type(x) is int for x in result.keys())
>>> assert all(type(x) is str for x in result.values())

>>> pprint(result)
{1: 'January',
 2: 'February',
 3: 'March',
 4: 'April',
 5: 'May',
 6: 'June',
 7: 'July',
 8: 'August',
 9: 'September',
 10: 'October',
 11: 'November',
 12: 'December'}
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result: dict[int,str]

# %% Data
DATA = [
    (1, 'January'),
    (2, 'February'),
    (3, 'March'),
    (4, 'April'),
    (5, 'May'),
    (6, 'June'),
    (7, 'July'),
    (8, 'August'),
    (9, 'September'),
    (10, 'October'),
    (11, 'November'),
    (12, 'December'),
]

# %% Result
result = ...

# %% About
# - Name: Comprehension Types Zfill
# - 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. Define `result: dict` with `DATA` converted into:
#    - Keys: month number
#    - Values: month name
# 2. Month number must be two letter string (zero padded)
# 3. Use dict comprehension
# 4. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result: dict` z `DATA` przekonwertowanym w:
#    - klucz: numer miesiąca
#    - wartość: nazwa miesiąca
# 2. Numer miesiąca ma być dwuznakowym stringiem (wypełnij zerem)
# 3. Użyj rozwinięcia słownikowego
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Example
# {'01': 'January',
#  '02': 'February',
#  '03': 'March',
#  ...
#  '11': 'November',
#  '12': 'December'}

# %% Hints
# - `f'{number:02}'`
# - `str.zfill()`

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

>>> type(result)
<class 'dict'>
>>> '00' not in result
True
>>> '13' not in result
True
>>> result['01'] == 'January'
True

>>> assert all(type(x) is str for x in result.keys())
>>> assert all(type(x) is str for x in result.values())
>>> assert all(len(x) == 2 for x in result.keys())

>>> pprint(result)
{'01': 'January',
 '02': 'February',
 '03': 'March',
 '04': 'April',
 '05': 'May',
 '06': 'June',
 '07': 'July',
 '08': 'August',
 '09': 'September',
 '10': 'October',
 '11': 'November',
 '12': 'December'}
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result: dict[str,str]

# %% Data
DATA = [
    (1, 'January'),
    (2, 'February'),
    (3, 'March'),
    (4, 'April'),
    (5, 'May'),
    (6, 'June'),
    (7, 'July'),
    (8, 'August'),
    (9, 'September'),
    (10, 'October'),
    (11, 'November'),
    (12, 'December'),
]

# %% Result
result = ...