8.1. Unpack Getitem
Allows to get element from ordered sequence
Works with ordered sequences:
str
,list
,tuple
8.1.1. Syntax
Index must
int
(positive, negative or zero)Positive Index starts with
0
Negative index starts with
-1
>>> data = ['a', 'b', 'c']
>>>
>>>
>>> data[0]
'a'
>>>
>>> data[1]
'b'
>>>
>>> data[-1]
'c'
>>>
>>> data['a']
Traceback (most recent call last):
TypeError: list indices must be integers or slices, not str
8.1.2. Positive Index
Starts with
0
Index must be less than length of an object
Ascending
>>> data = ['a', 'b', 'c']
>>>
>>>
>>> data[0]
'a'
>>>
>>> data[1]
'b'
>>>
>>> data[2]
'c'
>>>
>>> data[3]
Traceback (most recent call last):
IndexError: list index out of range
8.1.3. Negative Index
0
is equal to-0
Starts with
-1
Descending
Negative index starts from the end and go right to left
>>> data = ['a', 'b', 'c']
>>>
>>>
>>> data[-0]
'a'
>>>
>>> data[-1]
'c'
>>>
>>> data[-2]
'b'
>>>
>>> data[-3]
'a'
>>>
>>> data[-4]
Traceback (most recent call last):
IndexError: list index out of range
>>> -0 == 0
True
8.1.4. Index Type
Index must int
(positive, negative or zero)
>>> data = ['a', 'b', 'c']
>>>
>>>
>>> data[1.0]
Traceback (most recent call last):
TypeError: list indices must be integers or slices, not float
>>>
>>> data['a']
Traceback (most recent call last):
TypeError: list indices must be integers or slices, not str
8.1.5. Getitem from str
Get Item from str
:
>>> data = 'abc'
>>>
>>>
>>> data[0]
'a'
>>>
>>> data[1]
'b'
>>>
>>> data[2]
'c'
>>>
>>> data[-0]
'a'
>>>
>>> data[-1]
'c'
>>>
>>> data[-2]
'b'
8.1.6. Getitem from list
Getitem from list
:
>>> data = ['a', 'b', 'c']
>>>
>>>
>>> data[0]
'a'
>>>
>>> data[1]
'b'
>>>
>>> data[2]
'c'
>>>
>>> data[-0]
'a'
>>>
>>> data[-1]
'c'
>>>
>>> data[-2]
'b'
8.1.7. Getitem from tuple
>>> data = ('a', 'b', 'c')
>>>
>>>
>>> data[0]
'a'
>>>
>>> data[1]
'b'
>>>
>>> data[2]
'c'
>>>
>>> data[-0]
'a'
>>>
>>> data[-1]
'c'
>>>
>>> data[-2]
'b'
8.1.8. Getitem from set
Getitem from set
is impossible. set
is unordered data structure:
>>> data = {'a', 'b', 'c', 'd'}
>>>
>>>
>>> data[0]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>>
>>> data[1]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>>
>>> data[2]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>>
>>> data[-0]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>>
>>> data[-1]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>>
>>> data[-2]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
8.1.9. Getitem from dict
Getitem with index on
dict
is not possible
Non-integer keys:
>>> data = {'a': 0, 'b': 1, 'c': 2}
>>>
>>> data[0]
Traceback (most recent call last):
KeyError: 0
>>>
>>> data['a']
0
Integer keys:
>>> data = {0: 'a', 1: 'b', 2: 'c'}
>>>
>>> data[0]
'a'
>>>
>>> data['a']
Traceback (most recent call last):
KeyError: 'a'
>>>
>>> data[-1]
Traceback (most recent call last):
KeyError: -1
8.1.10. Getitem from list[list]
Get elements from list
of list
:
>>> data = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>>
>>> data[0]
[1, 2, 3]
>>>
>>> data[0][1]
2
8.1.11. Getitem from list[tuple]
Get elements from list
of tuple
:
>>> data = [
... ('Mark', 'Watney'),
... ('Melissa', 'Lewis'),
... ('Rick', 'Martinez'),
... ]
>>>
>>> data[0]
('Mark', 'Watney')
>>>
>>> data[0][1]
'Watney'
>>>
>>> data[0][1][2]
't'
8.1.12. Getitem from list[dict]
>>> data = [
... {'firstname': 'Mark', 'lastname': 'Watney'},
... {'firstname': 'Melissa', 'lastname': 'Lewis'},
... {'firstname': 'Rick', 'lastname': 'Martinez'},
... ]
>>>
>>>
>>> data[0]
{'firstname': 'Mark', 'lastname': 'Watney'}
>>>
>>> data[0]['lastname']
'Watney'
>>>
>>> data[0]['lastname'][2]
't'
8.1.13. Getitem from list[Sequence]
list
of mixedSequence
, such as:list
,tuple
orstr
Get elements from list of sequences:
>>> data = [[1, 2, 3],
... (4, 5, 6),
... {7, 8, 9}]
List:
>>> data[0]
[1, 2, 3]
>>>
>>> data[0][1]
2
Tuple:
>>> data[1]
(4, 5, 6)
>>>
>>> data[1][0]
4
Set:
>>> data[2]
{8, 9, 7}
>>>
>>> data[2][0]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
8.1.14. Use Case - 1
>>> calendarium = {
... 1961: 'First Human Space Flight',
... 1969: 'First Step on the Moon',
... }
>>>
>>>
>>> calendarium[1961]
'First Human Space Flight'
>>>
>>> calendarium['1961']
Traceback (most recent call last):
KeyError: '1961'
8.1.15. Use Case - 2
>>> crew = {
... 0: 'Melissa Lewis',
... 1: 'Mark Watney',
... 2: 'Rick Martinez',
... }
>>>
>>>
>>> crew[0]
'Melissa Lewis'
>>>
>>> crew[1]
'Mark Watney'
>>>
>>> crew[2]
'Rick Martinez'
>>>
>>> crew[-0]
'Melissa Lewis'
>>>
>>> crew[-1]
Traceback (most recent call last):
KeyError: -1
8.1.16. 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: Unpack Getitem Header
# - Difficulty: easy
# - Lines: 1
# - Minutes: 3
# %% English
# 1. Define `result: tuple[str]`
# 2. Select header from `DATA` (row with index 0)
# 3. Write header to `result`
# 4. Non-functional requirements:
# - Use only indexes (`getitem`)
# - Do not use `str.split()`, `slice`, `for`, `while` etc.
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result: tuple[str]`
# 2. Wybierz nagłówek z `DATA` (wiersz o indeksie 0)
# 3. Zapisz nagłówek do `result`
# 4. Wymagania niefunkcjonalne:
# - Korzystaj tylko z indeksów (`getitem`)
# - Nie używaj `str.split()`, `slice`, `for`, `while` itp.
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> 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 tuple, \
'Variable `result` has invalid type, should be tuple'
>>> assert len(result) == 5, \
'Variable `result` length should be 5'
>>> result
('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species')
"""
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'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),
(4.9, 2.5, 4.5, 1.7, 'virginica'),
]
# Header from `DATA` (row with index 0)
# type: tuple[str]
result = ...
# %% 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: Unpack Getitem Positive
# - Difficulty: easy
# - Lines: 3
# - Minutes: 3
# %% English
# 1. Define `result_a: tuple` with row from `DATA` at index 2
# 2. Define `result_b: tuple` with row from `DATA` at index 4
# 3. Define `result_c: tuple` with row from `DATA` at index 6
# 4. Non-functional requirements:
# - Use only indexes (`getitem`)
# - Do not use `str.split()`, `slice`, `for`, `while` etc.
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result_a: tuple` z wierszem z `DATA` o indeksie 2
# 2. Zdefiniuj `result_b: tuple` z wierszem z `DATA` o indeksie 4
# 3. Zdefiniuj `result_c: tuple` z wierszem z `DATA` o indeksie 6
# 4. Wymagania niefunkcjonalne:
# - Korzystaj tylko z indeksów (`getitem`)
# - Nie używaj `str.split()`, `slice`, `for`, `while` itp.
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert result_a is not Ellipsis, \
'Assign your result to variable `result_a`'
>>> assert result_b is not Ellipsis, \
'Assign your result to variable `result_b`'
>>> assert result_c is not Ellipsis, \
'Assign your result to variable `result_c`'
>>> assert type(result_a) is tuple, \
'Variable `result_a` has invalid type, should be tuple'
>>> assert type(result_b) is tuple, \
'Variable `result_b` has invalid type, should be tuple'
>>> assert type(result_c) is tuple, \
'Variable `result_c` has invalid type, should be tuple'
>>> assert len(result_a) == 5, \
'Variable `result_a` length should be 5'
>>> assert len(result_b) == 5, \
'Variable `result_b` length should be 5'
>>> assert len(result_c) == 5, \
'Variable `result_c` length should be 5'
>>> result_a
(5.1, 3.5, 1.4, 0.2, 'setosa')
>>> result_b
(6.3, 2.9, 5.6, 1.8, 'virginica')
>>> result_c
(4.7, 3.2, 1.3, 0.2, 'setosa')
"""
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'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),
(4.9, 2.5, 4.5, 1.7, 'virginica'),
]
# Row from `DATA` at index 2
# type: tuple[float|str]
result_a = ...
# Row from `DATA` at index 4
# type: tuple[float|str]
result_b = ...
# Row from `DATA` at index 6
# type: tuple[float|str]
result_c = ...
# %% 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: Unpack Getitem Negative
# - Difficulty: easy
# - Lines: 3
# - Minutes: 3
# %% English
# 1. Define `result_a: tuple` with row from `DATA` at index -5
# 2. Define `result_b: tuple` with row from `DATA` at index -3
# 3. Define `result_c: tuple` with row from `DATA` at index -1
# 4. Non-functional requirements:
# - Use only indexes (`getitem`)
# - Do not use `str.split()`, `slice`, `for`, `while` etc.
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result_a: tuple` z wierszem z `DATA` o indeksie -5
# 2. Zdefiniuj `result_b: tuple` z wierszem z `DATA` o indeksie -3
# 3. Zdefiniuj `result_c: tuple` z wierszem z `DATA` o indeksie -1
# 4. Wymagania niefunkcjonalne:
# - Korzystaj tylko z indeksów (`getitem`)
# - Nie używaj `str.split()`, `slice`, `for`, `while` itp.
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert result_a is not Ellipsis, \
'Assign your result to variable `result_a`'
>>> assert result_b is not Ellipsis, \
'Assign your result to variable `result_b`'
>>> assert result_c is not Ellipsis, \
'Assign your result to variable `result_c`'
>>> assert type(result_a) is tuple, \
'Variable `result_a` has invalid type, should be tuple'
>>> assert type(result_b) is tuple, \
'Variable `result_b` has invalid type, should be tuple'
>>> assert type(result_c) is tuple, \
'Variable `result_c` has invalid type, should be tuple'
>>> assert len(result_a) == 5, \
'Variable `result_a` length should be 5'
>>> assert len(result_b) == 5, \
'Variable `result_b` length should be 5'
>>> assert len(result_c) == 5, \
'Variable `result_c` length should be 5'
>>> result_a
(4.7, 3.2, 1.3, 0.2, 'setosa')
>>> result_b
(7.6, 3.0, 6.6, 2.1, 'virginica')
>>> result_c
(4.9, 2.5, 4.5, 1.7, 'virginica')
"""
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'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),
(4.9, 2.5, 4.5, 1.7, 'virginica'),
]
# Row from `DATA` at index -5
# type: tuple[float|str]
result_a = ...
# Row from `DATA` at index -3
# type: tuple[float|str]
result_b = ...
# Row from `DATA` at index -1
# type: tuple[float|str]
result_c = ...
# %% 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: Unpack Getitem Select
# - Difficulty: easy
# - Lines: 4
# - Minutes: 5
# %% English
# 1. Create `result: list`
# - Append to `result` a row from `DATA` at index 0
# - Append to `result` a row from `DATA` at index 1
# - Append to `result` a row from `DATA` at index -1
# 2. Non-functional requirements:
# - Use only indexes (`getitem`)
# - Do not use `str.split()`, `slice`, `for`, `while` etc.
# 3. Run doctests - all must succeed
# %% Polish
# 1. Stwórz `result: list`
# - Dodaj do `result` wiersz z `DATA` o indeksie 0
# - Dodaj do `result` wiersz z `DATA` o indeksie 1
# - Dodaj do `result` wiersz z `DATA` o indeksie -1
# 2. Wymagania niefunkcjonalne:
# - Korzystaj tylko z indeksów (`getitem`)
# - Nie używaj `str.split()`, `slice`, `for`, `while` itp.
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - `list.append()`
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from pprint import pprint
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert len(result) == 3, \
'Variable `result` length should be 6'
>>> pprint(result)
[('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
(5.8, 2.7, 5.1, 1.9, 'virginica'),
(4.9, 2.5, 4.5, 1.7, 'virginica')]
"""
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'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),
(4.9, 2.5, 4.5, 1.7, 'virginica'),
]
# Empty list
# type: list[tuple]
result = ...
# Append row from DATA at index 0
...
# Append row from DATA at index 1
...
# Append row from DATA at index -1
...
# %% 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: Unpack Getitem Header/Data
# - Difficulty: easy
# - Lines: 11
# - Minutes: 5
# %% English
# 1. Separate header (first line) from rows
# 1. Define `header: tuple[str]` with a header (first line of `DATA`)
# 2. Define `rows: list[tuple]` with rows (all the other lines of `DATA`)
# 3. Do not use slice, i.e.: `data[1:5]`
# 4. Non-functional requirements:
# - Use only indexes (`getitem`)
# - Do not use `slice`, `str.split()`, `for`, `while` etc.
# - You can use copy and paste or vertically select `alt`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Odseparuj nagłówek (pierwsza linia) od danych
# 1. Zdefiniuj `header: tuple[str]` z nagłówkiem (pierwsza linia `DATA`)
# 2. Zdefiniuj `rows: list[tuple]` z wierszami (wszystkie inne linie `DATA`)
# 3. Nie używaj slice, tj. `data[1:5]`
# 4. Wymagania niefunkcjonalne:
# - Korzystaj tylko z indeksów (`getitem`)
# - Nie używaj `str.split()`, `slice`, `for`, `while` itp.
# - Możesz użyć kopiowania i wklejania oraz zaznaczania pionowego `alt`
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - `list.append()`
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from pprint import pprint
>>> assert header is not Ellipsis, \
'Assign your result to variable `header`'
>>> assert rows is not Ellipsis, \
'Assign your result to variable `rows`'
>>> assert type(header) is tuple, \
'Variable `header` has invalid type, should be tuple'
>>> assert all(type(x) is tuple for x in rows), \
'All elements in `rows` should be tuple'
>>> assert header not in rows, \
'Header should not be in `rows`'
>>> content = open(__file__).read()
>>> assert 'DATA'+'[1:]' not in content, \
'You should not use `slice`'
>>> assert 'DATA'+'[1:11]' not in content, \
'You should not use `slice`'
>>> pprint(header)
('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species')
>>> pprint(rows)
[(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'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),
(4.9, 2.5, 4.5, 1.7, 'virginica')]
"""
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'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),
(4.9, 2.5, 4.5, 1.7, 'virginica'),
]
# Define `header: tuple[str]` with a header (first line of `DATA`)
# type: tuple[str]
header = ...
# Define `rows: list[tuple]` with rows (all the other lines of `DATA`)
# Do not use slice, ie: `data[1:5]`
# type: list[tuple]
rows = ...