Индексация и срезы
Строки, списки и кортежи являются упорядоченными коллекциями, то есть их элементы имеют фиксированный порядок и свои собственные порядковые номера, называемые индексами. С их помощью можно как получать отдельные элементы коллекции, так и извлекать целые последовательности элементов.
Получение элементов по индексу
По индексу можно получить отдельные элементы строк, списков и кортежей. Например, у нас есть следующие переменные:
# Строка:
message_str = "Как дела?"
# Список:
shopping_list = ["Еда 1", "Еда 2", "Еда 3", "Еда 4", "Еда 5"]
# Кортеж:
friends_tuple = ("Друг 1", "Друг 2", "Друг 3")
Первый символ "К"
строки "Как дела?"
находится по индексу 0
, второй "а"
– по индекс 1
, и так далее.
Можно использовать не только положительные, но отрицательные индексы, которые позволяют обращаться к элементам с конца коллекции. В таком случае последний элемент "Друг 3"
кортежа friends
имеет индекс -1
, предпоследний – -2
, и так далее.
Чтобы получить элемент по его индексу, нужно указать имя переменной, содержащей коллекцию, и нужный индекс в квадратных скобках [ ]
:
коллекция[индекс]
Так мы можем получить отдельные символы строки и элементы списка и кортежа:
print(message_str[0])
# Вывод: К
print(message_str[3])
# Вывод: (Пробел тоже является отдельным символом)
print(shopping_list[4])
# Вывод: Еда 5
print(shopping_list[-3])
# Вывод: Еда 3
print(friends_tuple[0])
# Вывод: Друг 1
print(friends_tuple[-3])
# Вывод: Друг 1
Попытка обратиться к элементу по несуществующему индексу приведет к исключению IndexError:
# Так делать нельзя:
print(friends_tuple[9])
# Ошибка: IndexError: tuple index out of range
Индексация во вложенных коллекциях
Коллекции могут содержать другие коллекции, создавая вложенные структуры. Например, рассмотрим кортеж, содержащий два списка:
cities = (["Москва", "Санкт-Петербург"], ["Череповец", "Вологда"])
print(cities[1][0])
# Вывод: Череповец
Для доступа к элементу вложенной коллекции используется двойная индексация. Первый индекс [1]
обращается ко второму элементу кортежа: ["Череповец", "Вологда"]
, а второй индекс [0]
– к первому элементу этого вложенного списка: "Череповец"
.
Уровень вложенности коллекций может быть произвольным, что позволяет использовать более глубокую индексацию:
cities = (["Москва", "Санкт-Петербург"], ["Череповец", ["Вологда", "Шексна"]])
cities[1][1][0] = "Вологда"
print(cities)
# Вывод: Вологда
cities[1]
– возвращает второй элемент кортежа – список["Череповец", ["Вологда", "Шексна"]]
.cities[1][1]
– возвращает второй элемент списка – список["Вологда", "Шексна"]
.cities[1][1][0]
– возвращает первый элемент предыдущего списка – строку"Вологда"
.
Использование срезов
Для извлечения не одного элемента, а сразу целого подмножества элементов строки, списка и кортежа в Python предусмотрен удобный механизм срезов. Срез позволяет получить часть коллекции в соответствии с заданными параметрами, перечисленными через двоеточие:
коллекция[start:stop:step]
start
– начальный индекс среза (включительно), по умолчаниюstart=0
.stop
– конечный (не включительно) индекс среза.step
– шаг извлечения элементов, по умолчаниюstep=1
.

Срезы, как и функция range()
, используют параметры start
, stop
и step
, и одинаково задают границы и шаг получения элементов. Однако срезы применяются непосредственно к строкам, спискам и кортежам, позволяя выбирать их подмножества, тогда как range()
создает отдельную последовательность целых чисел. При этом создаваемая последовательность чисел соответствует индексам, выбираемым в срезе. То есть, задавая функции range()
границы и шаг, вы получаете именно те индексы, которые будут использованы при формировании среза с такими же параметрами.
Срез коллекции будет представлен тем же типом данным, что и сама коллекция: срезом строки будет строка (называемая подстрокой), срезом списка – список, а срезом кортежа – кортеж.
[start:stop:end]
, так как ни один из параметров среза не является обязательным. Рассмотрим возможные варианты получения среза коллекции без учёта шага:
[:]
– выбирает всю коллекцию целиком.[start:stop]
– выбирает все элементы с индексаstart
по индексstop
(не включая его).[start:]
– выбирает элементы от индексаstart
до конца коллекции.[:stop]
– выбирает элементы от начала коллекции до индексаstop
(не включая его).
Например, из строки "Как дела"
мы можем получить подстроку "дела"
c помощью среза с индекса 4
по индекс 7
(включительно). Так как элемент под конечным индексом не входит в срез, параметр stop
следует указать равным 8
, а не 7
:
print(message_str[4:8])
# Вывод: дела
Первое двоеточие является обязательностью частью конструкции среза, и если мы не укажем ни один из параметров, то создадим полную копию коллекции:
message_str_copy = message_str[:]
print(message_str_copy)
# Вывод: Как дела?
shopping_list_copy = shopping_list[:]
print(shopping_list_copy)
# Вывод: ["Еда 1", "Еда 2", "Еда 3", "Еда 4", "Еда 5"]
friends_tuple_copy = friends_tuple[:]
print(friends_tuple_copy)
# Вывод: ("Друг 1", "Друг 2", "Друг 3")
Если указать только параметр start
, то в срезе будут все элементы с индекса start
до конца коллекции:
print(message_str[4:])
# Вывод: дела?
print(shopping_list[2:])
# Вывод: ['Еда 3', 'Еда 4', 'Еда 5']
print(friends_tuple[1:])
# Вывод: ('Друг 2', 'Друг 3')
Параметр stop
без параметра start
, наоборот, позволяет получить все элементы с начала коллекции до индекса stop
(не включая его):
print(message_str[:3])
# Вывод: Как
print(shopping_list[:2])
# Вывод: ['Еда 1', 'Еда 2']
print(friends_tuple[:2])
# Вывод: ('Друг 1', 'Друг 2')
В срезах допускается использовать отрицательные индексы и даже совмещать их с положительными:
print(message_str[-9:-6])
# Вывод:Как
print(shopping_list[-4:5])
# Вывод: ['Еда 2', 'Еда 3', 'Еда 4', 'Еда 5']
print(friends_tuple[-2:])
# Вывод: ('Друг 2', 'Друг 3')
Шаг извлечения элементов
Параметр step
всегда указывается после второго двоеточия и определяет шаг извлечения элементов из коллекции. По умолчанию step=1
, то есть символы извлекаются последовательно слева направо. Но если указать step=2
, то будет извлечён каждый второй элемент:
print(message_str[::2])
# Вывод: Ккдл?
print(shopping_list[::2])
# Вывод: ['Еда 1', 'Еда 3', 'Еда 5']
print(friends_tuple[::2])
# Вывод: ('Друг 1', 'Друг 3')
Здесь мы не указали оба параметра start
и stop
, поэтому в качестве среза была взята вся коллекция.
Для получения элементов с нечетными индексами можно начать срез с индекса 1
:
print(message_str[1::2])
# Вывод: а еа
print(shopping_list[1::2])
# Вывод: ['Еда 2', 'Еда 4']
print(friends_tuple[1::2])
# Вывод: ('Друг 2',)
Использование отрицательного шага, например step=-1
, позволит получить коллекцию в обратном порядке:
print(message_str[::-1])
# Вывод: ?алед каК
print(shopping_list[::-1])
# Вывод: ['Еда 5', 'Еда 4', 'Еда 3', 'Еда 2', 'Еда 1']
print(friends_tuple[::-1])
# Вывод: ('Друг 3', 'Друг 2', 'Друг 1')
1. Дан список с числами: numbers = [10, 20, 30, 40, 50]
. Как получить третий элемент списка? Используйте как положительный, так и отрицательный индекс.
2. Дан кортеж, содержащий списки с названиями фруктов: fruits = (["Яблоко", "Банан"], ["Апельсин", "Киви"])
. Как получить слово "Банан"
?
colors = ["Красный", "Оранжевый", "Жёлтый", "Зелёный", "Голубой", "Синий", "Фиолетовый"]
. Какие срезы получатся, если использовать следующие конструкции:
colors[2:]
colors[1:4]
colors[-5:2]
colors[1::2]
colors[-2:-6:-1]
4. Создайте новую строку, состоящую из каждого третьего символа строки sentence = "Весна, весна на улице, весенние деньки!"
.
5. Измените порядок символов в строке user = "мадам"
, записав её задом наперёд.