Справочник по Python · модуль 5 · строки
Глава 5.3
center()
и count()
center() строит строку заданной ширины, дополняя текст с обеих сторон. count() считает непересекающиеся вхождения подстроки и умеет ограничивать поиск диапазоном. Оба метода возвращают результат, не меняя исходный текст.
- Категория
- Строковые методы
- Уровень
- Базовый
- Связанные темы
- Длина строки, срезы, поиск
- Зачем это знать
- Формировать текстовые поля и считать подстроки
§1Две задачи в одной главе
Методы center() и count() связаны только соседством в справочнике: первый оформляет текст, второй его исследует. Общего у них два свойства, важных для всех строковых методов.
- Ни один не меняет исходную строку — строки неизменяемы, возвращается новый результат.
- Оба принимают дополнительные параметры со значениями по умолчанию, и именно в этих параметрах прячутся неожиданности.
§2center(): дополнение до ширины
center(width, fillchar=" ") возвращает строку длиной width, в середине которой стоит исходный текст. Свободное место заполняется — по умолчанию пробелами.
label = "Python" print("|" + label.center(12) + "|")
| Python |
Вертикальные черты добавлены только для наглядности: без них пробелы по краям не видно. Ширина 12 относится к результату целиком, а не к добавленному заполнению.
width = 12 ┌───┬────────┬───┐ │ 3 │ Python │ 3 │ 3 + 6 + 3 = 12 └───┴────────┴───┘
§3Куда идёт лишний символ
Если свободных позиций нечётное число, разделить их поровну нельзя. Python отдаёт лишний символ правой стороне.
print("cat".center(8, "-")) print("cats".center(8, "-"))
--cat--- --cats--
В первом случае свободных позиций пять: две слева и три справа. Во втором их четыре, и они делятся поровну. Значит, точной симметрии от center() ждать нельзя — она получается только при совпадении чётности ширины и длины текста.
§4Символ заполнения
Второй параметр задаёт, чем заполнять свободное место. Он не обязателен, по умолчанию — пробел.
print("Отчёт".center(20, "="))
=======Отчёт========
Это типичное применение метода: заголовки секций в текстовом выводе, разделители в логах, простые «рамки» в консольных программах.
§5Ровно один символ
fillchar должен состоять ровно из одного символа. Ни пустая строка, ни две буквы не подойдут.
print("cat".center(8, "--"))
TypeError: The fill character must be exactly one character long
Ограничение не произвольное: метод дополняет строку до точной ширины, а из двухсимвольных блоков произвольную ширину не собрать.
§6Малая ширина не обрезает
Если width меньше длины строки, дополнять нечего — метод возвращает исходный текст целиком.
text = "Python" print(text.center(3, "-")) print("".center(5, "."))
Python .....
Легко решить, что text.center(10) всегда даёт ровно десять символов, и построить на этом выравнивание таблицы. Для длинного текста результат окажется шире, и колонки поедут. Если ширина обязательна, длину нужно ограничивать срезом: text[:10].center(10).
§7ljust() и rjust()
У center() есть два родственных метода с той же сигнатурой, но другим прижатием текста.
text = "Python" print(text.ljust(10, ".")) print(text.rjust(10, ".")) print(text.center(10, "."))
Python.... ....Python ..Python..
| Метод | Где текст | Типичное применение |
|---|---|---|
ljust(width) | прижат влево | названия, левая колонка таблицы |
rjust(width) | прижат вправо | числа, суммы, правая колонка |
center(width) | по середине | заголовки и разделители |
Для чисел с ведущими нулями есть отдельный метод zfill() — он разбирается в главе 5.10.
§8Практика: ровные колонки
Вместе эти методы дают простой способ вывести таблицу без внешних библиотек: названия прижимаем влево, числа — вправо.
rows = [("кот", 5), ("собака", 12), ("ёж", 3)] for name, count in rows: print(name.ljust(10, ".") + str(count).rjust(3))
кот....... 5 собака.... 12 ёж........ 3
Числа приходится переводить в строку через str(): методы выравнивания принадлежат строкам, у чисел их нет.
§9count(): подсчёт вхождений
count(substring) возвращает, сколько раз подстрока встречается в строке. Если не встречается — 0, а не ошибка.
text = "python api python tests" print(text.count("python")) print(text.count("java"))
2 0
Искать можно и один символ — это просто подстрока длиной один.
text = "мама мыла раму" print(text.count("ма")) print(text.count("а"))
2 4
§10Границы start и end
Полная форма — count(substring, start, end). Дополнительные параметры ограничивают область поиска, работая ровно как границы среза: start включается, end — нет.
text = "red | red red | red" print(text.count("red")) print(text.count("red", 7, 20)) print(repr(text[7:20]))
4 2 'ed red | red'
Третья строка показывает, что именно просматривается. Обратите внимание: первое red обрезано до ed и потому не считается, а вот red на границе end уместилось целиком. Запись text.count(part, start, end) равнозначна text[start:end].count(part), но не создаёт промежуточную строку.
§11Непересекающиеся вхождения
Метод считает только те совпадения, которые не накладываются друг на друга. Найдя вхождение, он продолжает поиск за его концом, а не со следующего символа.
print("aaa".count("aa")) print("aaaa".count("aa"))
1 2
a a a
└─┘ найдено на позициях 0–1
↑ поиск продолжается отсюда, слева одна «a» — не хватает
человек насчитал бы два: 0–1 и 1–2, но они перекрываются
Для перекрывающихся совпадений count() не подходит — их считают циклом с find() из главы 5.5, сдвигая позицию на один символ.
§12count() учитывает регистр
Совпадение проверяется посимвольно, поэтому Python и python — разные подстроки.
text = "Python PYTHON python" needle = "python" print(text.count(needle)) print(text.casefold().count(needle.casefold()))
1 3
Как и в главе 5.2, нормализовать нужно обе стороны: и строку, и искомую подстроку.
§13Пустая подстрока
Пустая строка считается подстрокой, которая находится в каждом промежутке между символами, а также перед первым и после последнего.
text = "abc" print(text.count(""))
4
│ a │ b │ c │ ↑ ↑ ↑ ↑ 0 1 2 3
Результат всегда равен len(text) + 1. Практической пользы в этом нет, но знать стоит: если подстрока приходит из переменной и та случайно оказалась пустой, счётчик покажет неожиданно большое число вместо нуля.
§14count() или in
Если нужно только выяснить, есть ли подстрока, count() — избыточный инструмент: он дочитывает строку до конца, даже когда ответ уже известен.
| Задача | Запись | Что делает |
|---|---|---|
| есть ли вообще | part in text | останавливается на первом совпадении |
| сколько раз | text.count(part) | проходит строку целиком |
| на какой позиции | text.find(part) | возвращает индекс первого вхождения |
Запись if text.count(part) > 0 работает верно, но if part in text и короче, и быстрее. Для длинного текста разница становится заметной: count() всегда просматривает всю строку.
§15Частые ошибки
| Что написано | Что произойдёт | Как правильно |
|---|---|---|
text.center(10, "--") | TypeError: заполнитель длиннее одного символа | text.center(10, "-") |
text.center("10") | TypeError: ширина должна быть числом | text.center(10) |
ждать обрезки от center(3) | длинная строка вернётся целиком | text[:3].center(3) |
считать, что center() делит поровну всегда | лишний символ уходит вправо | учитывать чётность при точной вёрстке |
text.center(10) без сохранения | результат выброшен, строка не изменилась | строки неизменяемы — сохранить результат |
text.count("PYTHON") для любого регистра | совпадёт только точная запись | нормализовать обе стороны через casefold() |
ждать два вхождения "aa" в "aaa" | вернётся 1: совпадения перекрываются | считать циклом с find() |
считать end включительной границей | символ по индексу end не войдёт | читать диапазон как срез [start:end] |
if text.count(part) > 0 | лишний проход по всей строке | if part in text |
§16Проверьте себя
Что произойдёт, если width меньше длины строки?
center() вернёт исходную строку целиком, без обрезки. Гарантии ширины метод не даёт.
Куда попадёт лишний символ заполнения?
Вправо. При нечётном числе свободных позиций справа окажется на один символ больше.
Чем ljust() отличается от rjust()?
Прижатием текста: ljust() оставляет его слева и дополняет справа, rjust() — наоборот.
Считает ли count() перекрывающиеся вхождения?
Нет. После совпадения поиск продолжается за его концом, поэтому "aaa".count("aa") равно 1.
Почему "abc".count("") равно 4?
Пустая строка находится на каждой границе: перед первым символом, между символами и после последнего. Всегда len(text) + 1.
Когда вместо count() лучше in?
Когда нужен только факт наличия. in останавливается на первом совпадении, а count() дочитывает строку до конца.
§17Шпаргалка
text.center(width, "-")text.ljust(w)text.rjust(w)text[:w].center(w)text.count(part)text.count(part, start, end)text.casefold().count(part.casefold())part in textИтог главы
center() дополняет короткую строку до указанной ширины одним символом заполнения, отдавая лишнюю позицию правой стороне; ширину он при этом не гарантирует — длинный текст возвращается целиком. Вместе с ljust() и rjust() он позволяет верстать ровные колонки. count() считает непересекающиеся вхождения с учётом регистра и может ограничить поиск границами start и end, которые читаются как границы среза.