Справочник по Python · модуль 3 · списки и циклы
Глава 3.9
Объект slice и
именованные срезы
Запись data[start:stop:step] можно сохранить как объект slice, дать ему имя, передать в функцию и повторно применять к разным последовательностям.
- Категория
- Продвинутая работа со срезами
- Уровень
- Продвинутый
- Связанные темы
- Срезы, строки, списки, кортежи
- Зачем это знать
- Заменять непонятные границы среза именованным правилом
§1Двоеточия создают объект с параметрами среза
Когда Python видит data[1:7:2], он передаёт объекту data правило выбора, эквивалентное slice(1, 7, 2). Функция slice() позволяет сохранить это правило отдельно от данных.
§2Создание объекта slice
| Запись | Соответствующий срез |
|---|---|
slice(stop) | [:stop] |
slice(start, stop) | [start:stop] |
slice(start, stop, step) | [start:stop:step] |
every_second = slice(1, 7, 2) numbers = [0, 10, 20, 30, 40, 50, 60, 70] print(numbers[every_second])
[10, 30, 50]
§3Обычный и объектный срез эквивалентны
text = "abcdefghij" print(text[2:8:2]) print(text[slice(2, 8, 2)])
ceg ceg
slice не хранит последовательность и не извлекает элементы сам. Он только хранит три параметра, которые последовательность применит позже.
§4Параметры доступны как атрибуты
part = slice(2, 10, 3) print(part.start) print(part.stop) print(part.step)
2 10 3
Атрибуты доступны только для чтения: после создания объект slice не меняется.
§5Пропущенная часть записывается как None
tail = slice(3, None) even_positions = slice(None, None, 2) print("abcdefgh"[tail]) print("abcdefgh"[even_positions])
defgh aceg
§6Отрицательный шаг меняет направление
reverse = slice(None, None, -1) print("python"[reverse]) print((1, 2, 3)[reverse])
nohtyp (3, 2, 1)
Шаг не может быть нулём: slice(None, None, 0) создаётся, но применение такого среза вызывает ValueError.
§7Одно правило применяется к разным типам
middle = slice(1, -1) print([10, 20, 30, 40][middle]) print("python"[middle]) print(("a", "b", "c")[middle])
[20, 30]
ytho
('b',)§8Имя объясняет смысл границ
line = "2026-09-06 INFO Server started" print(line[0:10]) print(line[11:15])
DATE = slice(0, 10) LEVEL = slice(11, 15) line = "2026-09-06 INFO Server started" print(line[DATE]) print(line[LEVEL])
Заглавные имена показывают, что правила считаются константами проекта. Теперь числа определены один раз, а место использования читается по смыслу.
§9slice можно передать в функцию
def extract(sequence, area): return sequence[area] first_three = slice(3) print(extract([10, 20, 30, 40], first_three)) print(extract("Python", first_three))
[10, 20, 30] Pyt
§10indices() приводит границы к длине
part = slice(-5, None, 2) print(part.indices(8))
(3, 8, 2)
Метод учитывает длину конкретной последовательности, отрицательные границы и направление шага. Обычно Python делает это сам, но indices() полезен при реализации собственных последовательностей.
§11Практический пример: поля фиксированного формата
PAYMENT_ID = slice(0, 6) STATUS = slice(7, 11) AMOUNT = slice(12, None) row = "A10482 PAID 001250" payment = { "id": row[PAYMENT_ID], "status": row[STATUS], "amount": int(row[AMOUNT]), } print(payment)
{'id': 'A10482', 'status': 'PAID', 'amount': 1250}Такой подход оправдан для действительно фиксированного формата. Для CSV, JSON и строк с разделителями следует применять инструменты этих форматов.
§12Частые ошибки
| Что написано | Что произойдёт | Как правильно |
|---|---|---|
slice(1, 5, 0) затем применён к списку | ValueError: шаг не может быть нулём | использовать ненулевой шаг |
| считать, что slice хранит данные | в объекте есть только границы | применять его как sequence[area] |
| ожидать ускорения от именованного среза | алгоритм выбора не изменится | использовать slice ради смысла и повторного применения |
давать имя каждому одноразовому data[:2] | код станет длиннее без новой информации | именовать повторяемые или предметно значимые границы |
| считать срез представлением исходного списка | обычный список вернёт новый список | учитывать поведение конкретного типа данных |
§13Проверьте себя
Что хранит объект slice?
Три параметра: start, stop и step. Самих элементов последовательности в нём нет.
Чему эквивалентен slice(None, None, -1)?
Обычному срезу [::-1], который читает последовательность в обратном направлении.
Когда именованный срез улучшает код?
Когда одни границы повторяются или имеют предметный смысл, который можно выразить понятным именем.
§14Шпаргалка
slice(stop)slice(start, stop)slice(start, stop, step)data[area]area.startarea.stoparea.steparea.indices(len(data))Итог главы
slice хранит правило выбора элементов отдельно от последовательности. Именованный срез полезен, когда границы повторяются, передаются в функцию или выражают поле фиксированного формата.