Модуль 3 · Списки и циклы

Справочник по Python · модуль 3 · списки и циклы

Глава 3.9

3.9

Объект slice и
именованные срезы

Запись data[start:stop:step] можно сохранить как объект slice, дать ему имя, передать в функцию и повторно применять к разным последовательностям.

Категория
Продвинутая работа со срезами
Уровень
Продвинутый
Связанные темы
Срезы, строки, списки, кортежи
Зачем это знать
Заменять непонятные границы среза именованным правилом

§1Двоеточия создают объект с параметрами среза

Когда Python видит data[1:7:2], он передаёт объекту data правило выбора, эквивалентное slice(1, 7, 2). Функция slice() позволяет сохранить это правило отдельно от данных.

data[1:7:2]↔data[slice(1, 7, 2)]

§2Создание объекта slice

ЗаписьСоответствующий срез
slice(stop)[:stop]
slice(start, stop)[start:stop]
slice(start, stop, step)[start:stop:step]
main.pyкаждый второй элемент
every_second = slice(1, 7, 2)
numbers = [0, 10, 20, 30, 40, 50, 60, 70]

print(numbers[every_second])
Выводиндексы 1, 3 и 5
[10, 30, 50]

§3Обычный и объектный срез эквивалентны

main.pyодно правило в двух формах
text = "abcdefghij"

print(text[2:8:2])
print(text[slice(2, 8, 2)])
Выводрезультаты совпали
ceg
ceg

slice не хранит последовательность и не извлекает элементы сам. Он только хранит три параметра, которые последовательность применит позже.

§4Параметры доступны как атрибуты

main.pyструктура объекта
part = slice(2, 10, 3)

print(part.start)
print(part.stop)
print(part.step)
Выводтри сохранённых значения
2
10
3

Атрибуты доступны только для чтения: после создания объект slice не меняется.

§5Пропущенная часть записывается как None

main.pyначало и конец не заданы
tail = slice(3, None)
even_positions = slice(None, None, 2)

print("abcdefgh"[tail])
print("abcdefgh"[even_positions])
Вывод[3:] и [::2]
defgh
aceg

§6Отрицательный шаг меняет направление

main.pyразворот всей последовательности
reverse = slice(None, None, -1)

print("python"[reverse])
print((1, 2, 3)[reverse])
Выводстрока и кортеж справа налево
nohtyp
(3, 2, 1)

Шаг не может быть нулём: slice(None, None, 0) создаётся, но применение такого среза вызывает ValueError.

§7Одно правило применяется к разным типам

main.pyодинаковые позиции
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 можно передать в функцию

main.pyфункция не знает границы заранее
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() приводит границы к длине

main.pyфактические параметры для длины 8
part = slice(-5, None, 2)
print(part.indices(8))
Выводstart, stop, step
(3, 8, 2)

Метод учитывает длину конкретной последовательности, отрицательные границы и направление шага. Обычно Python делает это сам, но indices() полезен при реализации собственных последовательностей.

§11Практический пример: поля фиксированного формата

main.pyразбор строки платежа
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.step
Нормализоватьarea.indices(len(data))

Итог главы

slice хранит правило выбора элементов отдельно от последовательности. Именованный срез полезен, когда границы повторяются, передаются в функцию или выражают поле фиксированного формата.

Глава 3.9 · Объект slice · Справочник по PythonАвтор: Макаров Максим Николаевич