Индексация строк
Каждый символ строки имеет индекс — порядковый номер позиции. Индексы начинаются с 0 (первый символ) и идут до len(s) - 1 (последний символ).
s = "Python"
# 0 1 2 3 4 5 — положительные индексы (слева направо)
# -6-5-4-3-2-1 — отрицательные индексы (справа налево)
print(s[0]) # P — первый символ
print(s[1]) # y — второй символ
print(s[2]) # t
print(s[5]) # n — последний символ (длина 6, индекс последнего = 5)
# Отрицательные индексы: -1 — последний, -2 — предпоследний и т.д.
print(s[-1]) # n — последний символ
print(s[-2]) # o — предпоследний
print(s[-3]) # h — третий с конца
print(s[-6]) # P — первый символ (len=6, -len = -6)
При выходе за границы индекса (s[100] или s[-100]) возникает ошибка IndexError: string index out of range.
Срезы строк [start:stop:step]
Срез (slice) извлекает подстроку по правилу [start:stop:step]:
start— начальный индекс (включительно). По умолчанию0.stop— конечный индекс (не включительно). По умолчанию — длина строки.step— шаг. По умолчанию1. Может быть отрицательным.
s = "Python Programming"
# 012345678901234567 — индексы для наглядности
print(s[0:6]) # "Python" — символы с 0 по 5 (6 не включается)
print(s[7:18]) # "Programming" — символы с 7 по 17
print(s[7:18:1]) # "Programming" — то же самое, шаг 1 явно
Важнейшее правило: start включается, stop — нет. Длина среза [a:b] равна b - a.
Пропуск параметров среза
Любой из трёх параметров можно опустить — подставятся значения по умолчанию:
s = "Python"
# Пропуск start — от начала строки
print(s[:3]) # "Pyt" — символы 0, 1, 2 (эквивалентно s[0:3])
# Пропуск stop — до конца строки
print(s[2:]) # "thon" — от индекса 2 до конца (эквивалентно s[2:len(s)])
# Пропуск обоих — копия всей строки
print(s[:]) # "Python" — копия строки (эквивалентно s[0:len(s)])
# Пропуск start и stop, только шаг
print(s[::2]) # "Pto" — каждый второй символ (эквивалентно s[0:len(s):2])
print(s[::3]) # "Ph" — каждый третий символ
Отрицательные индексы в срезах
Отрицательные индексы отсчитываются от конца строки. Особенно удобны, когда нужно взять «всё, кроме последних N символов» или «последние N символов»:
s = "Python Programming"
# Положительные и отрицательные индексы взаимозаменяемы
print(s[7:18]) # "Programming"
print(s[7:-1]) # "Programmin" — всё от 7 до предпоследнего (-1 не включается)
print(s[-11:18]) # "Programming" — start отрицательный, stop положительный
print(s[-11:-1]) # "Programmin"
# Последние N символов
print(s[-3:]) # "ing" — последние 3 символа
print(s[-5:]) # "mming" — последние 5 символов
# Всё, кроме последних N символов
print(s[:-3]) # "Python Programm" — всё, кроме последних 3
print(s[:-1]) # "Python Programmin" — всё, кроме последнего символа
Шаг в срезах
Параметр step задаёт, через сколько позиций брать следующий символ. По умолчанию step = 1 — каждый символ подряд.
s = "abcdefghij"
# 0123456789
print(s[::1]) # "abcdefghij" — каждый символ (по умолчанию)
print(s[::2]) # "acegi" — каждый второй (индексы 0,2,4,6,8)
print(s[::3]) # "adgj" — каждый третий (индексы 0,3,6,9)
print(s[::4]) # "aei" — каждый четвёртый
# Шаг с указанием границ
print(s[1:9:2]) # "bdfh" — от индекса 1 до 8, каждый второй
print(s[2:10:3]) # "cfi" — от индекса 2 до 9, каждый третий
Отрицательный шаг и разворот строки
Отрицательный шаг означает движение справа налево. При отрицательном шаге start должен быть правее stop (если они заданы явно).
s = "Python"
# Разворот строки — классический трюк [::-1]
print(s[::-1]) # "nohtyP" — строка задом наперёд
# Пошаговый разбор: [::-1] означает:
# start не задан > конец строки
# stop не задан > начало строки
# step = -1 > идём справа налево по одному символу
s2 = "ABCDEFGHIJ"
# Отрицательный шаг с границами
print(s2[7:2:-1]) # "HGFED" — от индекса 7 до 3 (индекс 2 не включается)
print(s2[:2:-1]) # "JIHGFED" — от конца до индекса 3
print(s2[7::-1]) # "HGFEDCBA" — от индекса 7 до начала
# Каждый второй справа налево
print(s2[::-2]) # "JHFDB" — каждый второй с конца
print(s2[9:0:-2]) # "JHFD" — от 9 до 1, каждый второй
Неизменяемость строк
Строки в Python неизменяемы (immutable). Нельзя изменить отдельный символ — можно только создать новую строку:
s = "hello"
# s[0] = "H" # Ошибка! TypeError: 'str' object does not support item assignment
# Правильно — создать новую строку через срез и конкатенацию
s_new = "H" + s[1:] # "Hello"
s_new = s.replace("h", "H") # "Hello" — тоже создаёт новую строку
# Исходная строка не изменилась
print(s) # "hello" — по-прежнему
Функция len()
len(s) возвращает количество символов в строке. Это полезно для проверки границ перед индексацией:
s = "Python"
print(len(s)) # 6
print(len("")) # 0 — пустая строка
print(len("Привет")) # 6 — кириллица считается посимвольно
# Безопасная индексация с проверкой границ
idx = 2
if idx < len(s):
print(s[idx]) # t — индекс в допустимых пределах
# Индекс последнего символа через len()
last_idx = len(s) - 1
print(s[last_idx]) # n — последний символ
print(s[-1]) # n — то же самое, но короче
Операторы in и not in
Оператор in проверяет, содержится ли подстрока в строке. not in — обратная проверка. Возвращают True или False:
s = "Python Programming"
print("Python" in s) # True — подстрока найдена
print("java" in s) # False — не найдена
print("java" not in s) # True — действительно отсутствует
print("P" in s) # True — отдельный символ тоже подстрока
print("" in s) # True — пустая строка содержится в любой строке
# Часто используется в условиях
if "Pro" in s:
print("Строка содержит 'Pro'")
# Проверка символов
char = "o"
if char in s:
print(f"Символ '{char}' найден")
Практические примеры
s = "Python Programming"
# Первое слово
first_word = s[:6]
print(first_word) # "Python"
# Последнее слово
last_word = s[7:]
print(last_word) # "Programming"
# Каждый второй символ, начиная с первого
print(s[::2]) # "Pto rgamn"
# Строка задом наперёд
print(s[::-1]) # "gnimmargorP nohtyP"
# Первая половина строки
mid = len(s) // 2
print(s[:mid]) # "Python P"
# Вторая половина строки
print(s[mid:]) # "rogramming"
# Проверить, заканчивается ли строка на "ing" (без .endswith)
tail = s[-3:]
print(tail == "ing") # True
Таблица: поведение среза при разных параметрах
| Выражение | start | stop | step | Результат для "Python" |
|---|---|---|---|---|
s[0:6] | 0 | 6 | 1 | Python |
s[:3] | 0 (умолч.) | 3 | 1 | Pyt |
s[2:] | 2 | len(s) (умолч.) | 1 | thon |
s[:] | 0 (умолч.) | len(s) (умолч.) | 1 | Python |
s[::2] | 0 (умолч.) | len(s) (умолч.) | 2 | Pto |
s[::-1] | конец (умолч.) | начало (умолч.) | -1 | nohtyP |
s[-3:] | -3 | len(s) (умолч.) | 1 | hon |
s[:-2] | 0 (умолч.) | -2 | 1 | Pyth |
s[4:1:-1] | 4 | 1 | -1 | oht |
s[::-2] | конец (умолч.) | начало (умолч.) | -2 | nhy |
⚠️ Важно: Синтаксис срезов
[start:stop:step]работает не только для строк, но и для любых последовательностей — списков (list), кортежей (tuple) и других. Мы изучим списки и кортежи в одном из следующих уроков, но уже сейчас полезно знать, что срезы везде работают по одним и тем же правилам.