Модуль 5 · Строки

Справочник по Python · модуль 5 · строки

Глава 5.3

5.3

center()
и count()

center() строит строку заданной ширины, дополняя текст с обеих сторон. count() считает непересекающиеся вхождения подстроки и умеет ограничивать поиск диапазоном. Оба метода возвращают результат, не меняя исходный текст.

Категория
Строковые методы
Уровень
Базовый
Связанные темы
Длина строки, срезы, поиск
Зачем это знать
Формировать текстовые поля и считать подстроки

§1Две задачи в одной главе

Методы center() и count() связаны только соседством в справочнике: первый оформляет текст, второй его исследует. Общего у них два свойства, важных для всех строковых методов.

  1. Ни один не меняет исходную строку — строки неизменяемы, возвращается новый результат.
  2. Оба принимают дополнительные параметры со значениями по умолчанию, и именно в этих параметрах прячутся неожиданности.

§2center(): дополнение до ширины

center(width, fillchar=" ") возвращает строку длиной width, в середине которой стоит исходный текст. Свободное место заполняется — по умолчанию пробелами.

main.pyширина 12, текст из 6 символов
label = "Python"
print("|" + label.center(12) + "|")
Выводпо три пробела с каждой стороны
|   Python   |

Вертикальные черты добавлены только для наглядности: без них пробелы по краям не видно. Ширина 12 относится к результату целиком, а не к добавленному заполнению.

Схемаиз чего складывается ширина
width = 12
┌───┬────────┬───┐
│ 3 │ Python │ 3 │   3 + 6 + 3 = 12
└───┴────────┴───┘

§3Куда идёт лишний символ

Если свободных позиций нечётное число, разделить их поровну нельзя. Python отдаёт лишний символ правой стороне.

main.pyпять свободных позиций на две стороны
print("cat".center(8, "-"))
print("cats".center(8, "-"))
Вывод2+3 и 2+2
--cat---
--cats--

В первом случае свободных позиций пять: две слева и три справа. Во втором их четыре, и они делятся поровну. Значит, точной симметрии от center() ждать нельзя — она получается только при совпадении чётности ширины и длины текста.

§4Символ заполнения

Второй параметр задаёт, чем заполнять свободное место. Он не обязателен, по умолчанию — пробел.

main.pyзаголовок отчёта
print("Отчёт".center(20, "="))
Выводготовый разделитель
=======Отчёт========

Это типичное применение метода: заголовки секций в текстовом выводе, разделители в логах, простые «рамки» в консольных программах.

§5Ровно один символ

fillchar должен состоять ровно из одного символа. Ни пустая строка, ни две буквы не подойдут.

main.pyзаполнение из двух символов
print("cat".center(8, "--"))
Ошибкаограничение на длину заполнителя
TypeError: The fill character must be exactly one character long

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

§6Малая ширина не обрезает

Если width меньше длины строки, дополнять нечего — метод возвращает исходный текст целиком.

main.pyширина меньше длины
text = "Python"

print(text.center(3, "-"))
print("".center(5, "."))
Выводтекст не пострадал; пустая строка заполнена целиком
Python
.....
center() не гарантирует ширину

Легко решить, что text.center(10) всегда даёт ровно десять символов, и построить на этом выравнивание таблицы. Для длинного текста результат окажется шире, и колонки поедут. Если ширина обязательна, длину нужно ограничивать срезом: text[:10].center(10).

§7ljust() и rjust()

У center() есть два родственных метода с той же сигнатурой, но другим прижатием текста.

main.pyтри способа занять десять позиций
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Практика: ровные колонки

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

main.pyдве колонки фиксированной ширины
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, а не ошибка.

main.pyесть и нет
text = "python api python tests"

print(text.count("python"))
print(text.count("java"))
Выводдва вхождения и ноль
2
0

Искать можно и один символ — это просто подстрока длиной один.

main.pyслог и отдельная буква
text = "мама мыла раму"

print(text.count("ма"))
print(text.count("а"))
Выводслогов два, букв «а» четыре
2
4

§10Границы start и end

Полная форма — count(substring, start, end). Дополнительные параметры ограничивают область поиска, работая ровно как границы среза: start включается, end — нет.

main.pyвся строка и её часть
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Непересекающиеся вхождения

Метод считает только те совпадения, которые не накладываются друг на друга. Найдя вхождение, он продолжает поиск за его концом, а не со следующего символа.

main.pyсколько «aa» в «aaa»
print("aaa".count("aa"))
print("aaaa".count("aa"))
Выводне 2 и не 3
1
2
Схемапочему в «aaa» только одно
a a a
└─┘        найдено на позициях 0–1
    ↑      поиск продолжается отсюда, слева одна «a» — не хватает

человек насчитал бы два: 0–1 и 1–2, но они перекрываются

Для перекрывающихся совпадений count() не подходит — их считают циклом с find() из главы 5.5, сдвигая позицию на один символ.

§12count() учитывает регистр

Совпадение проверяется посимвольно, поэтому Python и python — разные подстроки.

main.pyточный и нормализованный подсчёт
text = "Python PYTHON python"
needle = "python"

print(text.count(needle))
print(text.casefold().count(needle.casefold()))
Вывододно точное и три без учёта регистра
1
3

Как и в главе 5.2, нормализовать нужно обе стороны: и строку, и искомую подстроку.

§13Пустая подстрока

Пустая строка считается подстрокой, которая находится в каждом промежутке между символами, а также перед первым и после последнего.

main.pyсколько пустых строк в «abc»
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, которые читаются как границы среза.

Глава 5.3 · center() и count() · Справочник по Python Автор: Макаров Максим Николаевич