Строки встречаются ребёнку раньше любых других данных: первая же программа что-то печатает, вторая что-то спрашивает. Но работать с ними всерьёз начинают позже, и тогда выясняется, что строка умеет значительно больше, чем просто выводиться на экран.

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

Строка — это последовательность

К каждому символу можно обратиться по номеру, так же как к элементу списка. Нумерация с нуля, отрицательные номера считаются с конца.

slovo = 'Python'
print(slovo[0])     # P
print(slovo[-1])    # n
print(slovo[1:4])   # yth
print(slovo[::-1])  # nohtyP
print(len(slovo))   # 6

Срезы работают так же, как в списках: правая граница не входит, поэтому [1:4] даёт три символа. Запись [::-1] переворачивает строку — кратчайший способ проверить, является ли слово палиндромом, и один из первых трюков, который дети переписывают друг у друга.

Методы, которые нужны на самом деле

МетодЧто делаетПример результата
upper()все заглавныеPYTHON
lower()все строчныеpython
capitalize()первая заглавнаяPython
strip()убирает пробелы по краямтекст без отступов
replace(a, b)заменяет все вхожденияновая строка
split()режет на список словсписок
join(spisok)склеивает список в строкустрока
find(a)номер символа или -1число
count(a)сколько раз встретилосьчисло
startswith(a)начинается ли сTrue или False
isdigit()состоит ли из цифрTrue или False

Две последние строки полезнее, чем кажутся. Проверка isdigit() позволяет запросить у пользователя число и не упасть, если он ввёл слово: сначала проверяем, потом преобразуем. Без неё первая же программа с вводом падает, стоит кому-то нажать Enter не ту клавишу.

Метод find() отличается от похожего index() одной деталью: когда ничего не найдено, первый тихо возвращает минус единицу, а второй останавливает программу ошибкой. Для проверки «есть ли такое вообще» надёжнее взять in: запись 'a' in slovo читается лучше обоих.

f-строки: сборка текста из чисел

Самый удобный способ собрать сообщение — поставить перед кавычками букву f и вписать переменные прямо в текст, в фигурных скобках.

imia = 'Olia'
ochki = 120
print(f'{imia} набрала {ochki} баллов')
print(f'Среднее: {ochki / 7:.2f}')

Вторая строка показывает заодно форматирование: двоеточие и .2f означают «показать два знака после запятой». Без этого деление даёт длинный хвост цифр, который в отчёте выглядит неопрятно.

До f-строк текст собирали плюсом, и этот способ до сих пор встречается в старых учебниках. Проблема в том, что плюс не умеет складывать текст с числом: 'Баллов: ' + 120 даёт ошибку, и приходится писать str(120) вокруг каждого числа. С f-строкой преобразование происходит само.

Строку нельзя изменить

Вот главная неожиданность темы. Попытка заменить один символ на месте не работает вообще:

slovo = 'Python'
slovo[0] = 'J'    # ошибка
slovo = 'J' + slovo[1:]   # а так правильно

Строки в Python неизменяемы: любой метод не правит имеющуюся, а возвращает новую. Поэтому запись slovo.upper() сама по себе ничего не меняет — результат надо куда-то положить, хотя бы обратно в ту же переменную. Это самая частая причина, по которой «метод не сработал»: он сработал, просто результат никуда не записали.

Списки в этом устроены наоборот, и ребёнку полезно увидеть оба случая рядом: тогда правило запоминается как отличие, а не как отдельный факт про строки.

input всегда даёт текст

Ещё одно место, где программа падает на ровном месте. Всё, что введено с клавиатуры, приходит строкой, даже если это цифры.

vozrast = input('Сколько тебе лет? ')
print(vozrast + 1)        # ошибка
print(int(vozrast) + 1)   # работает

Преобразование int() нужно каждый раз, когда введённое собираются считать. Если число дробное, берётся float(). А если пользователь ввёл слово, int() тоже падает — и именно здесь пригождается упомянутый выше isdigit().

Перебор строки циклом

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

slovo = 'programmirovanie'
glasnye = 'aeiouyаеёиоуыэюя'
schetchik = 0

for bukva in slovo:
    if bukva in glasnye:
        schetchik = schetchik + 1

print(schetchik)

Задача про подсчёт гласных выглядит школьной, но внутри неё три важные вещи сразу: перебор, проверка на вхождение и накопитель. Поэтому мы ставим её в программу именно после строк — она собирает воедино то, что до этого существовало по отдельности.

Если нужен не сам символ, а его номер, удобнее enumerate: он отдаёт пару «номер и символ» за один проход, и не приходится вести отдельную переменную-счётчик.

Длинный текст и перенос строки

Для многострочного текста берут три кавычки вместо одной. Всё, что внутри, сохраняется как есть, вместе с переносами:

pravila = '''Правила игры:
1. Три попытки
2. Подсказка стоит балл'''
print(pravila)

Второй способ — специальная пара символов внутри обычной строки, означающая переход на новую строку. Выглядит она как обратная косая черта с буквой n, и именно из-за неё чаще всего возникает путаница: в тексте её видно двумя символами, а на экране она превращается в перенос.

Ребёнку полезно сразу объяснить, что это не опечатка, а команда внутри текста. Рядом живут ещё две такие же: табуляция и сама обратная косая черта, которую, чтобы напечатать, приходится писать дважды.

split и join: туда и обратно

Эти два метода ходят парой и вместе решают большинство задач с текстом. Первый разрезает строку на список, второй собирает список обратно в строку.

predlozhenie = 'kot sidit na okne'
slova = predlozhenie.split()     # список из четырёх слов
print(len(slova))                # 4
print(' '.join(slova[::-1]))     # слова в обратном порядке

Без аргументов split() режет по любым пробелам, и лишние пробелы между словами его не смущают. Можно указать, по чему резать: split(',') разберёт строку с запятыми, и именно так читают простые таблицы.

Запись ' '.join(slova) сначала выглядит перевёрнутой: разделитель стоит впереди, а список в скобках. Логика в том, что склеивает именно разделитель, и это тот редкий случай, когда объяснение «так решили» работает хуже, чем просто запомнить форму.

Одна задача целиком

Чтобы методы перестали быть перечнем, полезно собрать из них что-то рабочее. Классическая задача — посчитать, сколько раз каждое слово встречается в тексте. Она короткая, и в ней работает всё сразу: приведение регистра, резка на слова, словарь как накопитель.

tekst = 'Kot sidit. Kot spit. Sobaka begaet.'
slova = tekst.lower().replace('.', ' ').split()
chastota = {}

for slovo in slova:
    chastota[slovo] = chastota.get(slovo, 0) + 1

print(chastota)

Вторую строку стоит разобрать отдельно: методы вызываются цепочкой, слева направо. Сначала всё становится строчными буквами, потом точки заменяются пробелами, и только после этого строка режется на слова. Поменять порядок — и точка приклеится к слову, а kot и Kot посчитаются как разные.

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

Три ошибки, которые повторяются

Первая: slovo.replace('a', 'o') написано отдельной строкой, а результат никуда не сохранён. Выглядит как «метод не работает».

Вторая: сравнение с разным регистром. Строка 'Да' не равна 'да', и викторина не засчитывает правильный ответ. Лечится приведением обеих сторон к нижнему регистру перед сравнением.

Третья: невидимые пробелы. Ответ, скопированный из другого места, часто приходит с пробелом на конце, и сравнение проваливается без видимой причины. Привычка писать .strip() сразу после input() снимает эту проблему навсегда.

Строки хорошо ложатся рядом со списками — их справочник здесь, а перебирать и то, и другое удобно циклом for. Что ломается в первых программах чаще всего, собрано в типичных ошибках новичков.