Python: Срезы строк

Работая со строками, мы часто сталкиваемся с задачей: извлечь часть строки. Например, получить год из даты, имя из полного ФИО или первые несколько символов из адреса электронной почты. Для таких случаев в Python существует мощный и удобный инструмент: срезы (или slices).

Что такое подстрока?

Подстрока является частью строки. То, что входит внутрь другой строки. Например, в строке '12-08-2034' подстрокой может быть '2034', '12' или даже '-'. Все зависит от того, какую информацию нам нужно извлечь.

Допустим, у нас есть строка с датой '12-08-2034'. Мы хотим получить из нее только год '2034'. В этой строке каждый символ имеет индекс (позицию), начиная с нуля:

'1' '2' '-' '0' '8' '-' '2' '0' '3' '4'
 0   1   2   3   4   5   6   7   8   9

Получается, год начинается с индекса 6 и заканчивается на 9. Чтобы извлечь его, мы используем срез:

value = "12-08-2034"
year = value[6:10]
print(year)  # => 2034

Срез value[6:10] берет символы с индекса 6 по 9 включительно. Формат среза:

строка[начало:конец]

Символ с индексом, указанным как "конец", не включается. Его можно воспринимать как естественный порядок символа, который нужно взять последним. То есть если там стоит 11, значит это будет 11 символ по порядку.

# Последний символ имеет индекс 10, а всего букв 11
value = "code-basics"

print(value[5:11])  # => basics (с 5 по 10 индекс)
print(value[0:7])  # => code-ba (с 0 по 6 индекс)
print(value[2:6])  # => de-b
print(value[:4])  # => code
print(value[5:])  # => basics

Как все это считать? Если мы работаем с конкретной строкой, то почти всегда это делается на глаз.

Срез является строкой

value = "01-12-9873"

value[1:2]  # => 1
value[3:5]  # => 12

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

part = value[3:7]  # => 12-9
print(part[0:2])  # => 12

Сначала мы получили подстроку "12-9", а потом сделали из нее новый срез "12".

Срез до конца или с начала

Иногда нужно взять часть строки до конца или от начала. Такие ситуации тоже легко обрабатываются срезами:

value = "Hexlet"

print(value[3:])  # => let     # С 3 символа до конца
print(value[:3])  # => Hex     # От начала до 3 символа

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

↩ Срезы с отрицательными индексами

Python позволяет считать слева направо и с конца строки. Для этого используются отрицательные индексы.

value = "Hexlet"

print(value[-1])  # => t      # Последний символ
print(value[3:-1])  # => le     # От 3 до предпоследнего
print(value[-5:3])  # => ex     # С 1 до 2

Индекс -1 в этом случае соответствует последнему символу в строке. Поэтому здесь мы видим разный результат:

print(value[3:-1])  # => le
print(value[3:])  # => let

Это удобно, когда заранее неизвестна длина строки, но нужно взять "хвост" или "середину" строки относительно конца.

Шаг в срезах

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

value = "Hexlet"

print(value[1:5:2])  # => el
# Индексы 1, 3 → символы e, l

В этом примере:

  • 1
    задает срез 'exle'
  • шаг 2 означает, что мы берем через один символ: 'e' и 'l'

Можно комбинировать с открытыми границами:

print(value[:5:2])  # => Hxe
print(value[1::2])  # => elt

Переворот строки

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

value = "Hexlet"

print(value[::-1])  # => telxeH

Строка читается с конца к началу. Очень удобно и лаконично.

Срезы с отрицательным шагом

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

value = "Hexlet"

print(value[4:1:-1])  # => elx
# Индексы: 4, 3, 2 → e, l, x

Python начнет с индекса 4 и пойдет влево до индекса 2 включительно. Индекс 1 в результат не входит.

Срез с переменными

Срезы не обязаны быть жестко зафиксированы числами. Можно использовать переменные:

start = 1
end = 5

value = "Hexlet"
print(value[start:end])  # => exle

Это особенно полезно, когда границы вычисляются во время работы программы.

Быстрая шпаргалка

value = "Hexlet"

value[::]  # Hexlet  — вся строка
value[:]  # Hexlet
value[::2]  # Hxe     — четные символы
value[1::2]  # elt     — нечетные символы
value[::-1]  # telxeH  — строка в обратном порядке
value[5:]  # t
value[:5]  # Hexle
value[-2:1:-1]  # elx     — с предпоследнего до третьего

Когда делаете срез от большего индекса к меньшему, обязательно задайте отрицательный шаг, иначе срез не сработает.

Не переживайте, если сейчас не запомните все комбинации: вы быстро начнете использовать их на практике. Главное понимать, как работает базовая структура строка[начало:конец:шаг].

Задание

Программа получает полный адрес сайта и должна выделить из него только имя домена — без протокола https://. В переменной url хранится адрес https://hexlet.io. Извлеките с помощью среза доменное имя hexlet.io и выведите на экран. Задание можно сделать разными способами.

Полезное

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются