6.4. Idiom Enumerate¶
Enumerate sequences
Built-in generator like (lazy evaluated)
enumerate(*iterables)
required
*iterables
- 1 or many sequences or iterator objectReturn an enumerate object
The enumerate object yields pairs containing a count (from start, which defaults to zero) and a value yielded by the iterable argument.
>>> from inspect import isgeneratorfunction, isgenerator
>>>
>>>
>>> isgeneratorfunction(enumerate)
False
>>> result = enumerate(['a', 'b', 'c'])
>>> isgenerator(result)
False
6.4.1. Problem¶
>>> months = ['January', 'February', 'March']
>>> result = []
>>>
>>> i = 0
>>>
>>> for month in months:
... result.append((i, month))
... i += 1
>>>
>>> result
[(0, 'January'), (1, 'February'), (2, 'March')]
6.4.2. Solution¶
>>> months = ['January', 'February', 'March']
>>> result = enumerate(months)
>>>
>>> list(result)
[(0, 'January'), (1, 'February'), (2, 'March')]
6.4.3. Lazy Evaluation¶
>>> months = ['January', 'February', 'March']
>>> result = enumerate(months)
>>>
>>> next(result)
(0, 'January')
>>> next(result)
(1, 'February')
>>> next(result)
(2, 'March')
>>> next(result)
Traceback (most recent call last):
StopIteration
6.4.4. Dict Conversion¶
>>> months = ['January', 'February', 'March']
>>> result = enumerate(months)
>>>
>>> dict(result)
{0: 'January', 1: 'February', 2: 'March'}
>>> months = ['January', 'February', 'March']
>>> result = enumerate(months, start=1)
>>>
>>> dict(result)
{1: 'January', 2: 'February', 3: 'March'}
>>> months = ['January', 'February', 'March']
>>> result = {f'{i:02}':month for i,month in enumerate(months, start=1)}
>>>
>>> print(result)
{'01': 'January', '02': 'February', '03': 'March'}
6.4.5. Using in a Loop¶
>>> months = ['January', 'February', 'March']
>>>
>>> for i, month in enumerate(months, start=1):
... print(f'{i} -> {month}')
1 -> January
2 -> February
3 -> March
6.4.6. Assignments¶
"""
* Assignment: Idiom Enumerate Start
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min
English:
1. Convert `MONTH` into dict:
a. key: int - month number
b. value: str - month name
2. Use enumerate()
3. Run doctests - all must succeed
Polish:
1. Przekonwertuj `MONTH` w słownik:
a. klucz: int - numer miesiąca
b. wartość: str - nazwa miesiąca
2. Użyj enumerate()
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `dict()`
* `enumerate()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from pprint import pprint
>>> assert type(result)
>>> assert -1 not in result
>>> assert 0 in result
>>> assert 12 not in result
>>> assert 13 not in result
>>> assert result[0] == 'January'
>>> assert all(type(x) is int for x in result.keys())
>>> assert all(type(x) is str for x in result.values())
>>> pprint(result, width=30, sort_dicts=False)
{0: 'January',
1: 'February',
2: 'March',
3: 'April',
4: 'May',
5: 'June',
6: 'July',
7: 'August',
8: 'September',
9: 'October',
10: 'November',
11: 'December'}
"""
MONTHS = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']
# number and month name
# type: dict[int,str]
result = ...
"""
* Assignment: Idiom Enumerate Start
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min
English:
1. Convert `MONTH` into dict:
a. key: int - month number
b. value: str - month name
2. Use enumerate() starting with 1
3. Run doctests - all must succeed
Polish:
1. Przekonwertuj `MONTH` w słownik:
a. klucz: int - numer miesiąca
b. wartość: str - nazwa miesiąca
2. Użyj enumerate() zaczynając od 1
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `dict()`
* `enumerate()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> 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())
>>> result # doctest: +NORMALIZE_WHITESPACE
{1: 'January',
2: 'February',
3: 'March',
4: 'April',
5: 'May',
6: 'June',
7: 'July',
8: 'August',
9: 'September',
10: 'October',
11: 'November',
12: 'December'}
"""
MONTHS = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']
# number and month name
# type: dict[int,str]
result = ...
"""
* Assignment: Idiom Enumerate Start
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min
English:
1. Convert `MONTH` into dict:
a. key: str - month number (convert to str)
b. value: str - month name
2. Use enumerate() starting with 1
3. Run doctests - all must succeed
Polish:
1. Przekonwertuj `MONTH` w słownik:
a. klucz: str - numer miesiąca (zamień na str)
b. wartość: str - nazwa miesiąca
2. Użyj enumerate() zaczynając od 1
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* dict comprehension
* `str()`
* `enumerate()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> type(result)
<class 'dict'>
>>> 0 not in result
True
>>> 13 not in result
True
>>> result[1] == 'January'
True
>>> assert all(type(x) is str for x in result.keys())
>>> assert all(type(x) is str for x in result.values())
>>> result # doctest: +NORMALIZE_WHITESPACE
{'1': 'January',
'2': 'February',
'3': 'March',
'4': 'April',
'5': 'May',
'6': 'June',
'7': 'July',
'8': 'August',
'9': 'September',
'10': 'October',
'11': 'November',
'12': 'December'}
"""
MONTHS = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']
# number and month name
# type: dict[str,str]
result = ...
"""
* Assignment: Idiom Enumerate ZeroPadded
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min
English:
1. Convert `MONTH` into dict:
a. key: str - month number
b. value: str - month name
2. Use enumerate() starting with 1
3. Month number must be two letter string
(zero padded) - np. 01, 02, ..., 09, 10, 11, 12
4. Run doctests - all must succeed
Polish:
1. Przekonwertuj `MONTH` w słownik:
a. klucz: str - numer miesiąca
b. wartość: str - nazwa miesiąca
2. Użyj enumerate() zaczynając od 1
3. Numer miesiąca ma być dwuznakowym stringiem
(dopełnionym zerem) - np. 01, 02, ..., 09, 10, 11, 12
4. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* dict comprehension
* `enumerate()`
* `str.zfill()`
* `f'{number:02}'`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> 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())
>>> result # doctest: +NORMALIZE_WHITESPACE
{'01': 'January',
'02': 'February',
'03': 'March',
'04': 'April',
'05': 'May',
'06': 'June',
'07': 'July',
'08': 'August',
'09': 'September',
'10': 'October',
'11': 'November',
'12': 'December'}
"""
MONTHS = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']
# With zero-padded number and month name
# type: dict[str,str]
result = ...
"""
* Assignment: Idiom Enumerate Dict
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min
English:
1. Define `result: dict`
2. Assign to `result` converted `DATA` to `dict`
3. Use `enumerate()`
4. Run doctests - all must succeed
Polish:
1. Zdefiniu `result: dict`
2. Przypisz do `result` przekonwertowane `DATA` do `dict`
3. Użyj `enumerate()`
4. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `dict()`
* `enumerate()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert type(result) is dict, \
'Variable `result` has invalid type, should be dict'
>>> assert all(type(x) is int for x in result.keys()), \
'All dict keys should be int'
>>> assert all(type(x) is str for x in result.values()), \
'All dict values should be str'
>>> result
{0: 'setosa', 1: 'versicolor', 2: 'virginica'}
"""
DATA = ['setosa', 'versicolor', 'virginica']
# Dict with enumerated DATA
# type: dict[int,str]
result = ...
"""
* Assignment: Idiom Enumerate Impl
* Complexity: medium
* Lines of code: 7 lines
* Time: 13 min
English:
1. Write own implementation of a built-in `enumerate()` function
2. Define function `myenumerate` with parameters:
a. parameter `iterable: list | tuple`
b. parameter `start: int`
3. Don't validate arguments and assume, that user will:
a. always pass valid type of arguments
b. iterable length will always be greater than 0
4. Do not use built-in function `enumerate()`
5. Run doctests - all must succeed
Polish:
1. Zaimplementuj własne rozwiązanie wbudowanej funkcji `enumerate()`
2. Zdefiniuj funkcję `myenumerate` z parametrami:
a. parametr `iterable: list | tuple`
b. parametr `start: int`
3. Nie waliduj argumentów i przyjmij, że użytkownik:
a. zawsze poda argumenty poprawnych typów
b. długość iterable będzie większa od 0
4. Nie używaj wbudowanej funkcji `enumerate()`
5. Uruchom doctesty - wszystkie muszą się powieść
Hint:
* https://github.com/python/cpython/blob/main/Objects/enumobject.c
* `range()`
* `len()`
* `list.appned()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isfunction
>>> assert isfunction(myenumerate)
>>> myenumerate(['January', 'February', 'March'])
[(0, 'January'), (1, 'February'), (2, 'March')]
>>> myenumerate(['January', 'February', 'March'], start=1)
[(1, 'January'), (2, 'February'), (3, 'March')]
>>> dict(myenumerate(['January', 'February', 'March'], start=1))
{1: 'January', 2: 'February', 3: 'March'}
"""
# Write own implementation of a built-in `enumerate()` function
# Define function `myenumerate` with parameters: `iterable`, `start`
# type: Callable[[Iterable, int], list[tuple]]
def myenumerate(iterable, start=0):
...