9.2. Unpack Slice

  • Slice argument must be int (positive, negative or zero)

  • Positive Index starts with 0

  • Negative index starts with -1

9.2.1. Slice Forwards

  • sequence[start:stop]

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data[0:3]
['a', 'b', 'c']
>>>
>>> data[3:5]
['d', 'e']

9.2.2. Slice Defaults

  • sequence[start:stop]

  • start defaults to 0

  • stop defaults to len(sequence)

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>> data[0:3]
['a', 'b', 'c']
>>>
>>> data[:3]
['a', 'b', 'c']
>>> data[3:5]
['d', 'e']
>>>
>>> data[3:]
['d', 'e']
>>>
>>> data[3:len(data)]
['d', 'e']
>>> data[:]
['a', 'b', 'c', 'd', 'e']

9.2.3. Slice Backwards

  • Negative index starts from the end and go right to left

>>> data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
... #        0    1    2    3    4    5    6    7    8    9
... #       -10  -9   -8   -7   -6   -5   -4   -3   -2   -1
>>>
>>> data[-3:-1]
['h', 'i']
>>>
>>> data[-3:]
['h', 'i', 'j']
>>>
>>> data[0:-3]
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>>
>>> data[:-3]
['a', 'b', 'c', 'd', 'e', 'f', 'g']

9.2.4. Step Forward

  • Every n-th element

  • sequence[start:stop:step]

  • start defaults to 0

  • stop defaults to len(sequence)

  • step defaults to 1

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>> data[0:5:1]
['a', 'b', 'c', 'd', 'e']
>>> data[0:5:2]
['a', 'c', 'e']
>>>
>>> data[1:5:2]
['b', 'd']
>>> data[:5:2]
['a', 'c', 'e']
>>>
>>> data[1::2]
['b', 'd']
>>> data[::2]
['a', 'c', 'e']

9.2.5. Step Backward

  • Every n-th element

  • sequence[start:stop:step]

  • start defaults to 0

  • stop defaults to len(sequence)

  • step defaults to 1

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data[5:0:-1]
['e', 'd', 'c', 'b']
>>>
>>> data[5::-1]
['e', 'd', 'c', 'b', 'a']
>>>
>>> data[:0:-1]
['e', 'd', 'c', 'b']
>>>
>>> data[5::-2]
['e', 'c', 'a']
>>>
>>> data[:0:-2]
['e', 'c']
>>>
>>> data[::-1]
['e', 'd', 'c', 'b', 'a']
>>>
>>> data[::-2]
['e', 'c', 'a']

9.2.6. Out of Range

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data[0:100]
['a', 'b', 'c', 'd', 'e']

9.2.7. Index Arithmetic

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> start = 1
>>> stop = 5
>>> step = 1
>>>
>>> data[start:stop:step]
['b', 'c', 'd', 'e']
>>>
>>> data[start-1:stop-2:step]
['a', 'b', 'c']

9.2.8. Slice Errors

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data['a':'e']
Traceback (most recent call last):
TypeError: slice indices must be integers or None or have an __index__ method
>>>
>>> data[::0]
Traceback (most recent call last):
ValueError: slice step cannot be zero
>>>
>>> data[:10.0]
Traceback (most recent call last):
TypeError: slice indices must be integers or None or have an __index__ method

9.2.9. Slice str

>>> data = 'abcde'
>>>
>>> data[0:3]
'abc'
>>>
>>> data[-3:]
'cde'
>>>
>>> data[::2]
'ace'

9.2.10. Slice tuple

>>> data = ('a', 'b', 'c', 'd', 'e')
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data[0:3]
('a', 'b', 'c')
>>>
>>> data[-3:]
('c', 'd', 'e')
>>>
>>> data[::2]
('a', 'c', 'e')

9.2.11. Slice list

>>> data = ['a', 'b', 'c', 'd', 'e']
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data[0:3]
['a', 'b', 'c']
>>>
>>> data[-3:]
['c', 'd', 'e']
>>>
>>> data[::2]
['a', 'c', 'e']

9.2.12. Slice set

Slicing set is not possible:

>>> data = {'a', 'b', 'c', 'd', 'e'}
... #        0    1    2    3    4
... #       -5   -4   -3   -2   -1
>>>
>>> data[0:3]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable

9.2.13. Slice dict

  • Slicing on dict is not possible

>>> data = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> data[0:3]
Traceback (most recent call last):
KeyError: slice(0, 3, None)
>>>
>>> data['a':'d']
Traceback (most recent call last):
KeyError: slice('a', 'd', None)

9.2.14. Nested Sequences

>>> data = [
...     [1, 2, 3],
...     [4, 5, 6],
...     [7, 8, 9]
... ]
>>>
>>> data[:2]
[[1, 2, 3], [4, 5, 6]]
>>>
>>> data[:2][1:]
[[4, 5, 6]]
>>>
>>> data[:2][1:][0]
[4, 5, 6]
>>>
>>> data[:2][1:][0][1:]
[5, 6]
>>>
>>> data[:2][1:][0][1:][1]
6

9.2.15. Column Selection

Column selection unfortunately does not work on list:

>>> data = [[1, 2, 3],
...         [4, 5, 6],
...         [7, 8, 9]]
...
>>> data[:]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>>
>>> data[:][1]
[4, 5, 6]
>>>
>>> data[:, 1]
Traceback (most recent call last):
TypeError: list indices must be integers or slices, not tuple

However this syntax is valid in numpy and pandas.

9.2.16. Use Case - 1

>>> from pprint import pprint
>>>
>>>
>>> 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'),
... ]
>>>
>>>
>>> pprint(DATA[1:])
[(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')]
>>>
>>> pprint(DATA[1::2])
[(5.8, 2.7, 5.1, 1.9, 'virginica'),
 (5.7, 2.8, 4.1, 1.3, 'versicolor'),
 (6.4, 3.2, 4.5, 1.5, 'versicolor')]
>>>
>>> pprint(DATA[1::-2])
[(5.8, 2.7, 5.1, 1.9, 'virginica')]
>>>
>>> pprint(DATA[:1:-2])
[(4.7, 3.2, 1.3, 0.2, 'setosa'),
 (6.3, 2.9, 5.6, 1.8, 'virginica'),
 (5.1, 3.5, 1.4, 0.2, 'setosa')]
>>>
>>> pprint(DATA[:-5:-2])
[(4.7, 3.2, 1.3, 0.2, 'setosa'), (6.3, 2.9, 5.6, 1.8, 'virginica')]
>>>
>>> pprint(DATA[1:-5:-2])
[]

9.2.17. Use Case - 2

>>> data = [[1, 2, 3],
...         [4, 5, 6],
...         [7, 8, 9]]
...
>>> data[::2]
[[1, 2, 3],
 [7, 8, 9]]
>>>
>>> data[::2][1]
[7, 8, 9]
>>>
>>> data[::2][:1]
[[1, 2, 3]]
>>>
>>> data[::2][1][1:]
[8, 9]

9.2.18. Use Case - 3

>>> text = 'We choose to go to the Moon!'
>>> word = 'Moon'
>>>
>>>
>>> start = text.find(word)
>>> stop = start + len(word)
>>>
>>> text[start:stop]
'Moon'
>>>
>>> text[:start]
'We choose to go to the '
>>>
>>> text[stop:]
'!'
>>>
>>> text[:start] + text[stop:]
'We choose to go to the !'

9.2.19. Assignments

# %% About
# - Name: Unpack Slice Text
# - Difficulty: easy
# - Lines: 6
# - Minutes: 8

# %% 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. From each `DATA_*` variable remove scientific title, military rank, etc.
# 2. Define `result_a: str` with text 'Alice Apricot' sliced from `DATA_A`
# 3. Define `result_b: str` with text 'Bob Banana' sliced from `DATA_B`
# 4. Define `result_c: str` with text 'Carol Corn' sliced from `DATA_C`
# 5. Define `result_d: str` with text 'Dave Durian' sliced from `DATA_D`
# 6. Define `result_e: str` with text 'Eve Elderberry' sliced from `DATA_E`
# 7. Define `result_f: str` with text 'Mallory Melon' sliced from `DATA_F`
# 8. Use `slice` to extract text
# 10. Run doctests - all must succeed

# %% Polish
# 1. Z każdej zmiennej `DATA_*` usuń tytuł naukowy i stopnia wojskowego
# 2. Define `result_a: str` z tekstem 'Alice Apricot' wyciętym z `DATA_A`
# 3. Define `result_b: str` z tekstem 'Bob Banana' wyciętym z `DATA_B`
# 4. Define `result_c: str` z tekstem 'Carol Corn' wyciętym z `DATA_C`
# 5. Define `result_d: str` z tekstem 'Dave Durian' wyciętym z `DATA_D`
# 6. Define `result_e: str` z tekstem 'Eve Elderberry' wyciętym z `DATA_E`
# 7. Define `result_f: str` z tekstem 'Mallory Melon' wyciętym z `DATA_F`
# 8. Użyj `slice` to wycięcia tekstu
# 10. Uruchom doctesty - wszystkie muszą się powieść

# %% Doctests
"""
>>> 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 type(result_a) is str, \
'Variable `result_a` has invalid type, should be str'

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

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

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

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

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

>>> result_a
'Alice Apricot'
>>> result_b
'Bob Banana'
>>> result_c
'Carol Corn'
>>> result_d
'Dave Durian'
>>> result_e
'Eve Elderberry'
>>> result_f
'Mallory Melon'
"""

# %% 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_a: str
result_b: str
result_c: str
result_d: str
result_e: str
result_f: str

# %% Data
EXAMPLE = 'lt. John Doe, PhD'
example = EXAMPLE[4:-5]
# 'John Doe'

DATA_A = 'prof. Alice Apricot'
DATA_B = 'Bob Banana, PhD'
DATA_C = 'lt. col. Carol Corn'
DATA_D = 'dr Dave Durian'
DATA_E = 'Eve Elderberry\t'
DATA_F = 'dr Mallory Melon, MD-PhD'

# %% Result
result_a = ...
result_b = ...
result_c = ...
result_d = ...
result_e = ...
result_f = ...

# %% About
# - Name: Unpack Slice Substr
# - Difficulty: easy
# - Lines: 3
# - Minutes: 5

# %% 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: str` with `TEXT` without `REMOVE` fragment
# 2. Expected output: 'The quick brown lazy dog'
# 3. Use `str.find()`, `len()` and slice
# 4. Do not use `str.replace()`
# 5. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result: str` z `TEXT` bez fragmentu `REMOVE`
# 2. Oczekiwany wynik: 'The quick brown lazy dog'
# 3. Użyj `str.find()`, `len()` oraz slice
# 4. Nie używaj `str.replace()`
# 5. Uruchom doctesty - wszystkie muszą się powieść

# %% 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 str, \
'Variable `result` has invalid type, should be str'

>>> result
'The quick brown lazy dog'
"""

# %% 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: str

# %% Data
TEXT = 'The quick brown fox jumps over the lazy dog'
REMOVE = 'fox jumps over the '

# %% Result
result = ...

# %% About
# - Name: Unpack Slice Sequence
# - Difficulty: easy
# - Lines: 2
# - Minutes: 3

# %% 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. Create set `result` with every second element from `a` and `b`
# 2. Run doctests - all must succeed

# %% Polish
# 1. Stwórz zbiór `result` z co drugim elementem `a` i `b`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% 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 set, \
'Variable `result` has invalid type, should be set'

>>> result
{0, 2, 4}
"""

# %% 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: set[int]

# %% Data
a = (0, 1, 2, 3)
b = [2, 3, 4, 5]

# %% Result
result = ...

# %% About
# - Name: Unpack Slice Header/Rows
# - Difficulty: easy
# - Lines: 2
# - Minutes: 3

# %% 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 `header: tuple` with a header (first line of `DATA`)
# 2. Define `rows: list` with rows (all the other lines of `DATA`)
# 3. Use slice, i.e.: `list[start:stop:step]`
# 4. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `header: tuple` z nagłówkiem (pierwsza linia `DATA`)
# 2. Zdefiniuj `rows: list` z wierszami (wszystkie inne linie `DATA`)
# 3. Użyj slice, tj. `list[start:stop:step]`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Doctests
"""
>>> 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`'

>>> pprint(header)
('firstname', 'lastname', 'age')

>>> pprint(rows)
[('Alice', 'Apricot', 30),
 ('Bob', 'Banana', 31),
 ('Carol', 'Corn', 32),
 ('Dave', 'Durian', 33),
 ('Eve', 'Elderberry', 34),
 ('Mallory', 'Melon', 15)]
"""

# %% 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
header = tuple[str,str,str]
rows = list[tuple[str,str,int]]

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

# %% Result
header = ...
rows = ...