Строки: обработка текста

Учимся обрабатывать текст в программах: измерять строки, брать символы и части, искать и преобразовывать.

Строка — это последовательность символов: букв, цифр, пробелов и знаков. С ней, как и со списком, можно делать много полезного.

Текст — самые частые данные

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

Длина и символы строки

У строки, как и у списка, есть длина (len) и индексы. Символы нумеруются с нуля.

slovo = "информатика"

print("Длина:", len(slovo))
print("Первый символ:", slovo[0])
print("Последний символ:", slovo[-1])

Вывод:

Длина: 11
Первый символ: и
Последний символ: а

Срезы: берём кусочек строки

Можно взять не один символ, а целый кусок — это называется срез. Пишут два индекса через двоеточие: slovo[начало:конец]. Как и в range, правый индекс не входит.

slovo = "информатика"

print(slovo[0:5])    # с 0 по 4 символ
print(slovo[5:])     # с 5 до конца
print(slovo[::-1])   # весь текст задом наперёд

Вывод:

инфор
матика
акитамрофни

Срез [::-1] — красивый приём: он переворачивает строку. Пригодится, например, чтобы проверить слово на палиндром (читается одинаково в обе стороны, как «шалаш»).

Методы строк

У строк есть встроенные «умения» — методы. Их вызывают через точку после строки. Вот самые ходовые:

МетодЧто делает
.upper()сделать ВСЕ буквы заглавными
.lower()сделать все буквы строчными
.count(x)сколько раз встречается x
.replace(a, b)заменить a на b
.split()разбить на слова (по пробелам)

Особенно полезен split: он превращает строку-предложение в список слов, и дальше с ними можно работать как со списком.

Попробуй сам

Сделаем мини-анализатор текста: посчитаем символы, слова, гласные буквы и развернём фразу. Это настоящая обработка текста, которую делают и большие программы — только в масштабе побольше.

fraza = "информатика это интересно"

print("Символов всего:", len(fraza))
print("Заглавными:", fraza.upper())

# Считаем слова через split
slova = fraza.split()
print("Слова:", slova)
print("Сколько слов:", len(slova))

# Считаем гласные буквы
glasnye = "аеёиоуыэюя"
schetchik = 0
for bukva in fraza:
    if bukva in glasnye:
        schetchik = schetchik + 1
print("Гласных букв:", schetchik)

print("Задом наперёд:", fraza[::-1])

Вывод:

Символов всего: 25
Заглавными: ИНФОРМАТИКА ЭТО ИНТЕРЕСНО
Слова: ['информатика', 'это', 'интересно']
Сколько слов: 3
Гласных букв: 11
Задом наперёд: онсеретни отэ акитамрофни

Поменяй fraza на свою — анализатор пересчитает всё заново. Обрати внимание на конструкцию bukva in glasnye: она проверяет, входит ли символ в строку гласных. Так удобно проверять принадлежность.

Соединение строк

Строки можно склеивать знаком + (как мы уже видели) и повторять знаком *: "ха" * 3 даёт "хахаха". Эти мелочи часто выручают при формировании текста для вывода.

Строка неизменна — и это нормально

Есть важное отличие строки от списка, которое стоит усвоить. Список можно менять прямо на месте: добавить элемент, заменить по индексу. А строку изменить «на месте» нельзя — она неизменяема. Если написать slovo[0] = "Х", Python выдаст ошибку. Но это не проблема: когда нужно «изменить» строку, мы просто создаём новую на основе старой. Например, slovo = slovo.upper() не меняет исходную строку, а делает новую (заглавную) и кладёт её обратно в переменную. Поэтому все методы строк — upper, replace, lower — возвращают новую строку, а не трогают старую. Это поначалу удивляет, но к этому быстро привыкаешь, и в больших программах такое поведение даже удобнее: ты уверен, что исходная строка случайно не испортится где-то в другом месте.

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

Задача: подсчёт слов в тексте

Соберём изученное в полезную программу — счётчик частоты слов. Такие счётчики лежат в основе поисковиков и анализаторов текста: они показывают, какие слова встречаются чаще всего. Разобьём текст на слова и для каждого посчитаем, сколько раз оно встретилось.

text = "кот спит кот ест кот играет собака спит"

slova = text.split()           # разбили на слова
print("Всего слов:", len(slova))

# Считаем, сколько раз встречается каждое слово
schetchik = {}
for slovo in slova:
    if slovo in schetchik:
        schetchik[slovo] = schetchik[slovo] + 1
    else:
        schetchik[slovo] = 1

print("Частота слов:")
for slovo, skolko in schetchik.items():
    print(" ", slovo, "-", skolko)

Вывод:

Всего слов: 8
Частота слов:
  кот - 3
  спит - 2
  ест - 1
  играет - 1
  собака - 1

Здесь мы встретили новый инструмент — словарь (schetchik = {}). Если список нумерует элементы числами, то словарь хранит пары «ключ — значение»: слово и сколько раз оно встретилось. Для каждого слова мы либо увеличиваем счётчик, либо заводим новый. Так за несколько строк программа разобрала текст и нашла самое частое слово — «кот». Поменяй text на свой и посмотри на частоты. Это именно тот приём, которым анализируют большие тексты: считают, какие слова важны, ищут повторы, выявляют темы.

Частые ошибки

  • Забывать скобки у методов. Пишут slovo.upper(), а не slovo.upper.
  • Думать, что методы меняют саму строку. Они возвращают новую строку; исходная не меняется.
  • Ошибаться с границей среза. Правый индекс в срезе не включается, как в range.

Запомни

  • Строка похожа на список символов: есть длина, индексы (с нуля) и срезы.
  • Срез [a:b] берёт кусок; [::-1] переворачивает строку.
  • Методы upper, lower, count, replace, split обрабатывают текст.
  • Проверка символ in строка говорит, входит ли символ в строку.
Проверьте себя
1. Что вернёт срез "привет"[0:3]?
Aприв
Bивет
Cпр
Dпри
2. Что делает метод split() без аргументов?
AРазбивает строку на список слов по пробелам
BСоединяет слова
CДелает буквы заглавными
DСчитает символы
3. Что вернёт "шалаш"[::-1]?
Aшалаш
Bшалаш (то же самое)
Cшалаш наоборот будет другим
Dошибку
4. Меняет ли метод upper() саму исходную строку?
AДа, исходная становится заглавной
BТолько в циклах
CНет, он возвращает новую строку, исходная не меняется
DЗависит от длины

Закрепите практикой

Задачи с автоматической проверкой — решайте прямо здесь, не уходя из учебника.