Модуль 4 · Урок 4.1
Строки
Индексы и срезы, неизменяемость, методы строк и подсчёт фрагментов с перекрытием.
Программы постоянно работают с текстом: имя, слово, запись числа, строка из файла. В задачах ЕГЭ часто нужно найти в длинной строке символ, кусок или повтор. Python берёт из строки символ по номеру, кусок по срезу и строит из старой строки новую. Срезы устроены как range из прошлого урока: начало включено, граница нет.
Индексы и срезы покажем на строках "PYTHON" и "ABCDEFG", а потом соберём новую строку из символов старой.
Длина и индексы
У строки есть длина и элементы, пронумерованные с нуля. Порядок символов важен: "кот" и "ток" состоят из одинаковых букв, но являются разными строками.
word = "PYTHON"print(len(word))print(word[0])print(word[2])print(word[-1])len получает количество элементов. Индекс — номер позиции. Положительные индексы начинаются с 0: это удобно понимать как число шагов от начала. Для строки длины n допустимы индексы от 0 до n - 1. Отрицательные индексы считают с конца: −1 — последний элемент, −2 — предпоследний.
Обращение к word[6] вызывает ошибку: такой позиции нет.
word = "PYTHON"print(word[6])У пустой строки "" длина 0, поэтому в ней нет даже элемента с индексом 0. Отдельного встроенного типа «символ» в Python нет: word[0] тоже строка, просто длины 1.
Срезы
Срез берёт элементы от начала до остановки, не включая её. Срез получает последовательность элементов по правилу s[start:stop:step]. Остановка не включается, как в range.
s = "ABCDEFG"print(s[1:4])print(s[:3])print(s[4:])print(s[::2])print(s[::-1])print(s[5:1:-1])s[1:4] берёт индексы 1, 2, 3 — ровно как range(1, 4). Для положительного шага пропущенное начало означает начало строки, пропущенная остановка — её конец. Для отрицательного шага значения по умолчанию меняются: движение начинается с конца и идёт до начала. Поэтому s[::-1] разворачивает всю строку, а s[5:1:-1] идёт от индекса 5 вниз до 2.
Тонкости:пропущенная граница и −1
Пропущенная граница и явно написанное -1 — не одно и то же. В s[5:-1:-1] явное -1 означает последний индекс, то есть 6: движение от 5 назад к 6 не даёт ни одного символа, срез пуст. Пропущенная граница при отрицательном шаге означает «до самого начала».
Срез за пределами длины обрезается: s[:100] вернёт всю строку. Одиночный неверный индекс вызывает ошибку. Срез может быть пустым; это нормальный результат. Шаг 0 недопустим.
Проверь срезы сам. Песочница начинается с s[::2] — каждый второй символ. Поле start или stop можно оставить пустым, шаг — сделать отрицательным. Номер под буквой — очередь, в которой срез её берёт.
Неизменяемость
Строку нельзя изменить на месте — можно только построить новую. Неизменяемость означает, что нельзя заменить элемент внутри существующей строки:
s = "кот"s[0] = "р"Можно построить новую строку и связать с ней имя:
s = "кот"s = "р" + s[1:]print(s)+ соединяет строки. Это действие называют конкатенацией. "ab" * 3 повторяет текст и создаёт "ababab". Старая строка при этом не меняется: имя просто связывается с новой.
Перебор и сборка строки
Новую строку собирают по символам: перебирают старую и добавляют нужные символы к накопителю. Строку нельзя изменить, но можно построить новую. Уберём из слова все буквы «а» — пройди программу по шагам и следи за result:
word = "банан"result = ""for ch in word: if ch != "а": result += chprint(result)for ch in word берёт символы по одному, как в уроке о for. Накопитель-строка начинается с пустой строки "" — как сумма с 0, а result += ch дописывает символ в конец.
Когда нужны соседние символы, перебирают индексы. Посчитаем пары одинаковых соседних букв — такие задачи встречаются в ЕГЭ:
s = "AABBBC"count = 0for i in range(len(s) - 1): if s[i] == s[i + 1]: count += 1print(count)У последнего символа соседа справа нет, поэтому индекс i идёт до len(s) - 2 включительно — это range(len(s) - 1). Пары AA, BB и ещё одна BB дают 3.
Методы строк
Метод — действие, которое вызывают у объекта через точку. Запись s.lower() означает «вызвать действие lower для строки s». Точка связывает действие с объектом, скобки запускают его.
Частые методы строки на примере s = "Banana" — выбери метод, чтобы увидеть результат:
- lower / upper
s.lower()→'banana'новая строка в нижнем регистре;s.upper()— в верхнем- strip
" Banana ".strip()→'Banana'пробелы и переводы строки по краям;rstrip— только справа- replace
s.replace("a", "o")→'Bonono'все вхождения; с третьим аргументом1— только первое- find
s.find("an")→1индекс первого вхождения, −1 если нет- count
s.count("an")→2неперекрывающиеся вхождения- startswith
s.startswith("Ba")→Trueendswith— проверка конца- zfill
"101".zfill(8)→'00000101'нули слева до длины 8- in
"nan" in s→Trueесть ли фрагмент внутри строки
Методы не меняют исходную строку. Вызов s.replace("a", "b") с проигнорированным результатом не обновляет s; для этого нужно присваивание.
s = " Python "clean = s.strip().lower()print(clean)print("th" in clean, clean.find("th"))print("101".zfill(8))Сначала strip создаёт промежуточную строку без крайних пробелов; затем lower вызывается уже для неё. Это два последовательных действия. zfill удобен, когда запись числа нужно выровнять по длине, например двоичную запись до восьми знаков.
Не проверяй поиск как if s.find(part):: индекс 0 ложен, а отсутствие с индексом −1 истинно. Используй part in s или явное сравнение с −1.
Тонкости:что именно убирает strip
strip("ab") убирает по краям любой набор символов a и b, а не обязательно целую подстроку "ab". Для удаления ровно одного известного префикса существует removeprefix.
count без перекрытий
count не считает перекрывающиеся вхождения. В "AAAA" фрагмент "AA" начинается на позициях 0, 1 и 2. Но "AAAA".count("AA") возвращает 2: после найденного совпадения поиск продолжится за ним.
count находит начала 0 и 2, а начало 1 пропускает: оно перекрывается с найденным.Для подсчёта всех начал можно проверить каждую позицию:
s = "AAAA"part = "AA"count = 0for i in range(len(s) - len(part) + 1): if s[i:i + len(part)] == part: count += 1print(count, s.count(part))Последнее допустимое начало — len(s) - len(part). Именно поэтому верхняя граница range на 1 больше. Если шаблон длиннее текста, диапазон пуст. С пустым шаблоном count ведёт себя неожиданно: "abc".count("") равно 4 — пустая строка «находится» перед каждым символом и в конце. Если шаблон может оказаться пустым, обработай этот случай отдельно.
Спецсимволы и Unicode
Некоторые символы записывают через обратный слеш, а сами символы — это коды Unicode. \n внутри обычной строки означает перевод строки, \t — табуляцию, \\ — один обратный слеш. Чтобы увидеть представление со специальными символами, используй repr:
s = "A\nB"print(len(s))print(repr(s))print(ord("A"), chr(66))Длина 3: A, перевод строки, B. Python хранит строки как Unicode-текст. ord("A") возвращает код символа, chr(66) — символ по коду. Обычная сортировка строк основана на кодах, а не на словарных правилах русского языка.
Тонкости:Unicode, эмодзи и isdigit
Некоторые визуально единые знаки, особенно эмодзи с модификаторами, состоят из нескольких кодовых точек: len считает именно кодовые точки, а не всегда видимые «картинки».
Строковые методы isdigit() и isalpha() работают шире набора английских букв и цифр ASCII. Если условие разрешает строго цифры 0–9, проверяй соответствующий набор. Пустая строка для isdigit() даёт False.
Итог
Теперь ты умеешь доставать из строки символы и куски и собирать из неё новые строки. Вот что понадобится дальше — и в задачах ЕГЭ на строки.
- ИндексыОт 0 до
len(s) - 1, отрицательные — с конца; неверный индекс —IndexError. s[start:stop:step]Граница не входит, как вrange;s[::-1]разворачивает строку.- НеизменяемостьСимвол заменить нельзя;
+и методы строят новую строку. - Сборка строки
result = ""иresult += chв циклеfor ch in s; соседние символы — черезrange(len(s) - 1). - Методы
lower,strip,replace,find,countвозвращают новый результат, строку не меняют. inЕсть ли фрагмент;findдаёт −1 при отсутствии, а 0 — это найденное начало.countСчитает без перекрытий; с перекрытиями — проверка каждой позиции срезом.
Проверьте себя
Ответь сначала сам, потом открой ответ.
Для s = "PYTHON" что дадут s[1], s[-2] и s[2:4]?
ОтветСкрыть ответ
Y, O и TH: индекс 4 в срез s[2:4] не входит.
Как одной записью развернуть строку? Что даст "ABCDEFG"[::3]?
ОтветСкрыть ответ
s[::-1]; [::3] берёт каждый третий символ — ADG.
Почему s[0] = "X" для s = "PYTHON" останавливает программу? Как получить строку «XYTHON»?
ОтветСкрыть ответ
Строка неизменяема — TypeError. Новая строка: s = "X" + s[1:].
Что напечатает программа?
result = ""for ch in "abc": result = ch + resultprint(result)ОтветСкрыть ответ
cba: каждый символ ставится перед уже собранной частью, поэтому строка разворачивается.
Что вернут "Python".find("th") и "Python".find("x")? Почему проверка if s.find("P"): для s = "Python" сработает неверно?
ОтветСкрыть ответ
2 и −1. s.find("P") вернёт 0 — это найденное начало, но 0 в условии ложен. Проверяй "P" in s.
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Напиши программу: палиндром ли слово
Слово-палиндром читается одинаково слева направо и справа налево. Напиши программу: вводится слово в одном регистре, программа печатает True, если это палиндром, иначе False. Запусти её для слов «топот» и «дом».
Запишите два значения через пробел: для «топот», затем для «дом».
Подсказка
Сравни слово с ним же, развёрнутым срезом [::-1].
Разбор
Например:
word = input()print(word == word[::-1])«топот» наоборот — «топот», «дом» наоборот — «мод».
Ответ: True False
Что напечатает программа?
s = "ИНФОРМАТИКА"print(len(s))print(s[0])print(s[-1])print(s[3])Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
Индексы начинаются с 0; −1 — последний символ.
Разбор
В слове 11 букв. Индекс 0 — И, −1 — последняя А, индекс 3 — четвёртая буква О.
Ответ: 11 И А О
Что напечатает программа?
s = "ABCDEFG"print(s[2:5])print(s[:4])print(s[::3])print(s[::-2])Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
Граница среза не входит; шаг 3 берёт каждый третий символ, отрицательный шаг идёт с конца.
Разбор
s[2:5] — индексы 2, 3, 4: CDE. s[:4] — ABCD. s[::3] — индексы 0, 3, 6: ADG. s[::-2] — с конца через один: GECA.
Ответ: CDE ABCD ADG GECA
Сколько раз «ана» входит в «банана»
Сколько раз «ана» входит в «банана» без перекрытий (как считает count) и с перекрытиями (как считает проверка каждой позиции срезом)?
Запишите два числа через пробел: без перекрытий, затем с перекрытиями.
Подсказка
Выпиши позиции, с которых начинается «ана»: их две, но они перекрываются.
Разбор
«ана» начинается с позиций 1 и 3. Вхождения перекрываются по букве «а», поэтому count находит только первое: 1. Проверка каждой позиции находит оба: 2.
Ответ: 1 2
Что напечатает программа?
print(" Мир ".strip().upper())print("a-b-c".replace("-", "", 1))Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
Методы выполняются слева направо. Третье значение в replace — сколько замен сделать.
Разбор
strip убирает пробелы по краям, upper делает буквы заглавными: МИР. replace с третьим значением 1 убирает только первый дефис: ab-c.
Ответ: МИР ab-c
Что напечатает программа?
print(ord("a"))print(chr(ord("a") + 2))print("7".zfill(3))Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
ord даёт код символа, chr — символ по коду; буквы идут подряд. zfill дописывает нули слева.
Разбор
Код «a» — 97; 97 + 2 = 99 — это «c». "7".zfill(3) — 007.
Ответ: 97 c 007
Сколько раз «AA» входит в «AAAAA»
Сколько раз "AA" входит в "AAAAA" по count и с перекрытиями?
Запишите два числа через пробел: по count, затем с перекрытиями.
Подсказка
«AA» может начаться с каждой позиции от 0 до 3. count после совпадения продолжает поиск за ним.
Разбор
count находит начала 0 и 2 — 2 раза. С перекрытиями подходят все начала 0, 1, 2, 3 — 4 раза.
Ответ: 2 4
Напиши программу: сумма цифр через строку
Напиши программу: вводится число, программа находит сумму его цифр, перебирая символы строки циклом for и превращая каждый в int. Запусти её для 9051.
Введите число.
Подсказка
input() даёт строку; for ch in s перебирает цифры-символы, int(ch) превращает каждую в число.
Разбор
Например:
s = input()total = 0for ch in s: total += int(ch)print(total)9 + 0 + 5 + 1 = 15.
Ответ: 15