12.6. Comprehension Nested
12.6.1. Syntax
result = [<RETURN> for <VARIABLE> in <ITERABLE> for <VARIABLE> in <ITERABLE>]
result = [<RETURN>
for <VARIABLE> in <ITERABLE>
for <VARIABLE> in <ITERABLE>]
12.6.2. Problem
>>> DATA = {
... 6: ['Doctorate', 'Prof-school'],
... 5: ['Masters', 'Bachelor', 'Engineer'],
... 4: ['HS-grad'],
... 3: ['Junior High'],
... 2: ['Primary School'],
... 1: ['Kindergarten'],
... }
>>>
>>>
>>> result = {}
>>> for lvl, titles in DATA.items():
... for title in titles:
... result[title] = lvl
>>>
>>> print(result)
{'Doctorate': 6,
'Prof-school': 6,
'Masters': 5,
'Bachelor': 5,
'Engineer': 5,
'HS-grad': 4,
'Junior High': 3,
'Primary School': 2,
'Kindergarten': 1}
12.6.3. Solution
>>> DATA = {
... 6: ['Doctorate', 'Prof-school'],
... 5: ['Masters', 'Bachelor', 'Engineer'],
... 4: ['HS-grad'],
... 3: ['Junior High'],
... 2: ['Primary School'],
... 1: ['Kindergarten'],
... }
>>>
>>>
>>> result = {title: lvl
... for lvl, titles in DATA.items()
... for title in titles}
>>>
>>> print(result)
{'Doctorate': 6,
'Prof-school': 6,
'Masters': 5,
'Bachelor': 5,
'Engineer': 5,
'HS-grad': 4,
'Junior High': 3,
'Primary School': 2,
'Kindergarten': 1}
12.6.4. Performance
>>> DATA = {
... 6: ['Doctorate', 'Prof-school'],
... 5: ['Masters', 'Bachelor', 'Engineer'],
... 4: ['HS-grad'],
... 3: ['Junior High'],
... 2: ['Primary School'],
... 1: ['Kindergarten'],
... }
>>> # %%timeit -r 1000 -n 1000
>>> result = {title: lvl
... for lvl, titles in DATA.items()
... for title in titles}
>>> # 2.22 µs ± 138 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
>>> # %%timeit -r 1000 -n 1000
>>> result = {t:l for l,ts in DATA.items() for t in ts}
>>> # 2.22 µs ± 181 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
>>> # %%timeit -r 1000 -n 1000
>>> result = {}
>>> for lvl, titles in DATA.items():
... for title in titles:
... result[title] = lvl
>>> # 2.24 µs ± 152 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
12.6.5. Convert to CSV
>>> DATA = [
... ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
... (5.8, 2.7, 5.1, 1.9, 'virginica'),
... (5.1, 3.5, 1.4, 0.2, 'setosa'),
... (5.7, 2.8, 4.1, 1.3, 'versicolor'),
... (6.3, 2.9, 5.6, 1.8, 'virginica'),
... (6.4, 3.2, 4.5, 1.5, 'versicolor'),
... (4.7, 3.2, 1.3, 0.2, 'setosa'),
... ]
>>> result = '\n'.join(','.join(str(x) for x in row) for row in DATA)
>>>
>>> print(result)
sepal_length,sepal_width,petal_length,petal_width,species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
6.3,2.9,5.6,1.8,virginica
6.4,3.2,4.5,1.5,versicolor
4.7,3.2,1.3,0.2,setosa
>>> result = [','.join(str(x) for x in row) for row in DATA]
>>> result = '\n'.join(result)
>>>
>>> print(result)
sepal_length,sepal_width,petal_length,petal_width,species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
6.3,2.9,5.6,1.8,virginica
6.4,3.2,4.5,1.5,versicolor
4.7,3.2,1.3,0.2,setosa
>>> data = []
>>> for row in DATA:
... line = ','.join(str(x) for x in row)
... data.append(line)
>>>
>>> result = '\n'.join(data)
>>>
>>> print(result)
sepal_length,sepal_width,petal_length,petal_width,species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
6.3,2.9,5.6,1.8,virginica
6.4,3.2,4.5,1.5,versicolor
4.7,3.2,1.3,0.2,setosa
12.6.6. Parse CSV
>>> DATA = '5.8,2.7,5.1,1.9\n5.1,3.5,1.4,0.2\n5.7,2.8,4.1,1.3'
>>>
>>> result = []
>>>
>>> for row in DATA.splitlines():
... row = row.split(',')
... result.append(row)
>>>
>>> print(result)
[['5.8', '2.7', '5.1', '1.9'],
['5.1', '3.5', '1.4', '0.2'],
['5.7', '2.8', '4.1', '1.3']]
>>> DATA = '5.8,2.7,5.1,1.9\n5.1,3.5,1.4,0.2\n5.7,2.8,4.1,1.3'
>>>
>>> [row.split(',') for row in DATA.splitlines()]
[['5.8', '2.7', '5.1', '1.9'],
['5.1', '3.5', '1.4', '0.2'],
['5.7', '2.8', '4.1', '1.3']]
>>> DATA = '5.8,2.7,5.1,1.9\n5.1,3.5,1.4,0.2\n5.7,2.8,4.1,1.3'
>>>
>>> [[float(x) for x in row.split(',')] for row in DATA.splitlines()]
[[5.8, 2.7, 5.1, 1.9],
[5.1, 3.5, 1.4, 0.2],
[5.7, 2.8, 4.1, 1.3]]
>>> DATA = '5.8,2.7,5.1,1.9,virginica\n5.1,3.5,1.4,0.2,setosa\n5.7,2.8,4.1,1.3,versicolor'
>>>
>>> def convert(x):
... try:
... return float(x)
... except ValueError:
... return x
>>>
>>> [[convert(x) for x in row.split(',')] for row in DATA.splitlines()]
[[5.8, 2.7, 5.1, 1.9, 'virginica'],
[5.1, 3.5, 1.4, 0.2, 'setosa'],
[5.7, 2.8, 4.1, 1.3, 'versicolor']]
12.6.7. Assignments
# %% 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
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: Comprehension Nested Dict
# - Difficulty: easy
# - Lines: 1
# - Minutes: 5
# %% English
# 1. Convert to `result: dict[str,int]`
# 2. Use nested dict comprehension
# 3. Run doctests - all must succeed
# %% Polish
# 1. Przekonwertuj do `result: dict[str,int]`
# 2. Użyj zagnieżdżonego rozwinięcia słownikowego
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - nested `for`
# - `dict.items()`
# - `str()`
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from pprint import pprint
>>> type(result)
<class 'dict'>
>>> pprint(result, sort_dicts=False)
{'Doctorate': 6,
'Prof-school': 6,
'Masters': 5,
'Bachelor': 5,
'Engineer': 5,
'HS-grad': 4,
'Junior High': 3,
'Primary School': 2,
'Kindergarten': 1}
"""
DATA = {
6: ['Doctorate', 'Prof-school'],
5: ['Masters', 'Bachelor', 'Engineer'],
4: ['HS-grad'],
3: ['Junior High'],
2: ['Primary School'],
1: ['Kindergarten'],
}
# Converted DATA
# type: dict[str,int]
result = ...