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 и выведите на экран. Задание можно сделать разными способами.

Полезное

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

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