Срезы в Python: как взять часть списка, строки или кортежа

Срез в Python записывается как nums[start:stop:step] и возвращает новый список, в который элемент с индексом stop не входит.

Разбираем отрицательные индексы, разворот через [::-1], замену и удаление элементов срезом, поверхностную копию и объект slice(). В конце шпаргалка и ошибки с IndexError и ValueError.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 3040 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3694 экспертных мнения Подписаться на Телеграм-канал
Обложка: Срезы в Python: как взять часть списка, строки или кортежа

Чтобы взять часть списка в Python, напишите после его имени квадратные скобки с двоеточием: nums[1:4]. Первое число говорит, с какого индекса начать, второе показывает, где остановиться, причём сам этот элемент в срез не попадает. Третье число необязательное и задаёт шаг: nums[::2] вернёт каждый второй элемент, а nums[::-1] развернёт список.

Срез одинаково работает для списков, строк и кортежей и всегда отдаёт новый объект, исходный остаётся прежним. Если вы только знакомитесь с языком, загляните сначала в основные команды Python: там разобраны списки и индексы, без них срезы не понять.

CheckroiCheckroiПодборка курсов по Python567 курсов • 51 школаСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Синтаксис среза: start, stop и step

Рой отрезает кусок от длинной ленты из пронумерованных ячеек

Общая форма записи такая:

последовательность[start:stop:step]
  • start: индекс первого элемента среза. Не указан, значит 0.
  • stop: индекс, перед которым срез останавливается. Не указан, значит до конца.
  • step: шаг. Не указан, значит 1, то есть подряд.

Любую из трёх частей можно пропустить. Если данные приходят строкой, сначала превратите её в список, способы есть в статье как преобразовать строку в список. А срезы посмотрим на списке из семи чисел:

nums = [10, 20, 30, 40, 50, 60, 70]
print(nums[1:4])    # [20, 30, 40]
print(nums[:3])     # [10, 20, 30]
print(nums[4:])     # [50, 60, 70]
print(nums[::2])    # [10, 30, 50, 70]
print(nums[1:6:2])  # [20, 40, 60]

Запомнить правило помогает картинка из официального учебника Python: индексы указывают не на элементы, а на границы между ними.

 +----+----+----+----+----+----+----+
 | 10 | 20 | 30 | 40 | 50 | 60 | 70 |
 +----+----+----+----+----+----+----+
 0    1    2    3    4    5    6    7
-7   -6   -5   -4   -3   -2   -1

Срез nums[1:4] берёт всё, что лежит между границами 1 и 4, то есть три числа. Длина среза равна разнице индексов, если оба индекса неотрицательные и не выходят за пределы списка.

Отрицательные индексы и разворот списка

Ряд кубиков с числами и его отражение в обратном порядке

Отрицательный индекс считается с конца: -1 означает последний элемент, -2 предпоследний. По документации Python подставляет вместо него len(s) + i.

nums = [10, 20, 30, 40, 50, 60, 70]
print(nums[-3:])     # [50, 60, 70]
print(nums[:-1])     # [10, 20, 30, 40, 50, 60]
print(nums[::-1])    # [70, 60, 50, 40, 30, 20, 10]
print(nums[5:1:-1])  # [60, 50, 40, 30]
print(nums[1:5:-1])  # []

С отрицательным шагом срез идёт справа налево, поэтому start должен быть больше stop. Перепутаете порядок, и получите пустой список без всякой ошибки, как в последней строке.

nums[::-1] возвращает перевёрнутую копию. Чтобы развернуть сам список на месте, есть метод reverse(), а для сортировки по убыванию sort(reverse=True). Как они устроены, мы разбирали в статье про метод sort() в Python.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Срезы строк и кортежей

Рой с ножницами довольно отрезает буквы от слова

Строки и кортежи режутся так же, как списки. Срез строки возвращает строку, срез кортежа возвращает кортеж.

word = "Python"
print(word[:2])     # Py
print(word[2:])     # thon
print(word[::-1])   # nohtyP

point = (3, 7, 1, 9)
print(point[1:3])   # (7, 1)

Разница в другом: строку и кортеж изменить нельзя. Попытка заменить символ по индексу падает с ошибкой:

word = "Python"
word[0] = "J"
# TypeError: 'str' object does not support item assignment

Решение: собрать новую строку из кусков, например "J" + word[1:] даст Jython. Для замены подстроки по значению удобнее метод replace(), а остальные приёмы со строками собраны в шпаргалке по методам строк.

Как изменить список через срез

Список, в отличие от строки, можно менять срезом. В учебнике Python прямо сказано, что присваивание срезу может даже изменить размер списка или очистить его целиком.

letters = ["a", "b", "c", "d", "e"]

letters[1:3] = ["B", "C", "X", "Y"]
print(letters)   # ['a', 'B', 'C', 'X', 'Y', 'd', 'e']

letters[1:1] = ["new"]
print(letters)   # ['a', 'new', 'B', 'C', 'X', 'Y', 'd', 'e']

del letters[::2]
print(letters)   # ['new', 'C', 'Y', 'e']

letters[:] = []
print(letters)   # []

Что здесь произошло по шагам:

  1. letters[1:3] = [...] заменил два элемента четырьмя, и список вырос.
  2. letters[1:1] = [...] вставил элемент без замены: срез нулевой длины работает как insert() при добавлении в список.
  3. del letters[::2] удалил каждый второй элемент, начиная с первого. Другие способы удаления описаны в статье как удалить элемент из списка.
  4. letters[:] = [] очистил список.

У среза с шагом есть ограничение. Если шаг не равен 1, по документации новая последовательность должна быть той же длины, что и заменяемый срез:

nums = [1, 2, 3, 4, 5, 6]
nums[::2] = [0, 0]
# ValueError: attempt to assign sequence of size 2 to extended slice of size 3

Срез создаёт копию, но поверхностную

Срез всегда возвращает новый список, поэтому nums[:] самый короткий способ скопировать список. Учебник Python называет такую копию поверхностной (shallow copy).

Копируется только сам список. Вложенные списки внутри него остаются общими:

original = [1, 2, [3, 4]]
copy_ = original[:]
copy_[0] = 100
copy_[2].append(5)

print(original)   # [1, 2, [3, 4, 5]]
print(copy_)      # [100, 2, [3, 4, 5]]

Число 100 появилось только в копии, а пятёрка попала в оба списка: внутренний [3, 4] у них один и тот же объект. Для полной копии вложенных структур есть функция copy.deepcopy():

import copy

original = [1, 2, [3, 4]]
deep = copy.deepcopy(original)
deep[2].append(5)
print(original)   # [1, 2, [3, 4]]

В NumPy всё наоборот. Срез массива не копирует данные, а даёт представление (view) исходного массива. В документации NumPy сказано, что массивы, полученные базовым срезом, всегда являются представлениями оригинала. Меняете срез, и меняется исходный массив.

import numpy as np

arr = np.array([1, 2, 3, 4, 5])
part = arr[1:3]
part[0] = 99
print(arr)   # [ 1 99  3  4  5]

Нужна независимая часть массива, добавьте .copy(): arr[1:3].copy(). Про NumPy для новичков мы писали в инструкции как суммировать список в Python.

Объект slice(): срез с именем

Запись a[1:4] Python превращает в объект slice. Его можно создать заранее функцией slice() и дать ему понятное имя. Пригодится, когда одни и те же границы повторяются в коде, например при разборе строк с полями фиксированной длины:

row = "2026-10-23;Москва;54000"
DATE = slice(0, 10)
YEAR = slice(0, 4)
print(row[DATE], row[YEAR])   # 2026-10-23 2026

Метод indices() показывает, во что превратятся границы для последовательности заданной длины. Так проще разобраться в чужом срезе, если с первого взгляда он непонятен:

print(slice(None, None, -1).indices(5))   # (4, -1, -1)
print(slice(2, 100).indices(5))           # (2, 5, 1)

Во второй строке граница 100 больше длины, и Python заменил её на 5. В обычном срезе он поступает так же.

Срезы по позициям подходят для строк, где поля всегда одной ширины. Если поля разделены точкой с запятой или запятой, надёжнее модуль csv, о нём в статье про формат CSV.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Шпаргалка: частые приёмы со срезами

Все примеры в таблице для списка nums = [10, 20, 30, 40, 50, 60, 70].

Задача Запись Результат
Первые три элемента nums[:3] [10, 20, 30]
Последние три элемента nums[-3:] [50, 60, 70]
Всё, кроме первого nums[1:] [20, 30, 40, 50, 60, 70]
Всё, кроме последнего nums[:-1] [10, 20, 30, 40, 50, 60]
Каждый второй с начала nums[::2] [10, 30, 50, 70]
Каждый второй со второго nums[1::2] [20, 40, 60]
Перевернуть nums[::-1] [70, 60, 50, 40, 30, 20, 10]
Скопировать nums[:] [10, 20, 30, 40, 50, 60, 70]

Срезом удобно разбить список на куски по три элемента и проверить слово на палиндром:

data = list(range(1, 11))
print([data[i:i + 3] for i in range(0, len(data), 3)])
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

w = "шалаш"
print(w == w[::-1])   # True

Ещё упражнения на списки и строки собраны в подборке 30 задач по Python для начинающих.

Частые ошибки со срезами

Ждёте, что stop войдёт в срез. nums[1:4] возвращает три элемента, а не четыре. Нужен элемент с индексом 4, пишите nums[1:5].

Ждёте ошибку при выходе за границы. Срез за пределами списка не падает, а возвращает то, что есть, или пустой список. Одиночный индекс за пределами даёт IndexError:

nums = [10, 20, 30]
print(nums[2:10])   # [30]
print(nums[10:])    # []
print(nums[10])     # IndexError: list index out of range

Так задумано: в учебнике сказано, что индексы среза за пределами строки обрабатываются аккуратно, без ошибки. Если пустой результат для вашей программы означает сбой, проверяйте длину списка сами.

Ставите шаг 0. Шаг не может быть нулём, на такой срез Python ответит ошибкой:

print(nums[::0])
# ValueError: slice step cannot be zero

Путаете a = [] и a[:] = []. Первая запись создаёт новый пустой список и привязывает к нему имя, вторая очищает существующий. Разница видна, когда на список ссылается ещё одна переменная:

a = [1, 2, 3]
b = a
a = []
print(b)   # [1, 2, 3]

a = [1, 2, 3]
b = a
a[:] = []
print(b)   # []

Даёте отрицательный шаг при прямом порядке границ. nums[1:5:-1] вернёт пустой список. С шагом -1 первая граница должна быть правее второй: nums[4:0:-1].

Где освоить Python системно

Срезы занимают небольшую часть языка. Дальше идут функции, работа с файлами, циклы и библиотеки. Если хотите пройти этот путь с наставником и проверкой домашних заданий, сравните программы в каталоге курсов по Python: цены, длительность и школы собраны на одной странице.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
Fullstack-разработчик на Python
Перейти на сайт курса
НетологияНетология137 000 ₽7125 ₽/мес.21 месяцОбзор курса
ДО Профессия Python-разработчик
Перейти на сайт курса
GeekBrainsGeekBrains149 001 ₽3167 ₽/мес.10 месяцевОбзор курса
Автоматизированное тестирование на Python
Перейти на сайт курса
SkillboxSkillbox122 226 ₽4108 ₽/мес.9 месяцевОбзор курса
Профессия Python-разработчик
Перейти на сайт курса
SkillFactorySkillFactory154 044 ₽4279 ₽/мес.10 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Python

Часто задаваемые вопросы

Входит ли последний индекс в срез Python?

Нет. Срез nums[1:4] берёт элементы с индексами 1, 2 и 3, а элемент с индексом 4 в него не попадает. Чтобы включить его, увеличьте stop на единицу: nums[1:5].

Как развернуть список с помощью среза?

Напишите nums[::-1]: шаг -1 проходит список с конца и возвращает перевёрнутую копию. Исходный список не меняется. Если нужно развернуть сам список, вызовите nums.reverse().

Копирует ли срез список?

Да, nums[:] создаёт новый список. Но копия поверхностная: вложенные списки остаются общими для оригинала и копии. Для полной копии используйте copy.deepcopy().

Что будет, если индекс в срезе больше длины списка?

Ошибки не будет. Python заменит такую границу длиной списка и вернёт то, что есть, или пустой список. IndexError появляется только при обращении к одному элементу, например nums[10].

Можно ли изменить строку через срез?

Нет, строки в Python неизменяемые, и присваивание по индексу или срезу вызовет TypeError. Соберите новую строку из кусков, например "J" + word[1:].

Чем срез массива NumPy отличается от среза списка?

Срез списка создаёт новый список, а базовый срез массива NumPy возвращает представление тех же данных. Изменения в таком срезе попадут в исходный массив. Чтобы получить независимую часть, вызовите .copy().

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!