Не смотря на один из принципов Python, гласящий: «Должен существовать один — и, желательно, только один – очевидный способ сделать что-то», в нашем любимом языке есть аж четыре способа отформатировать строку. Так сложилось исторически.
Это первый урок цикла, посвящённого форматированию строк. В него входят:
- Строковый оператор форматирования
- Метод format()
- f-Строки
- Шаблонные строки
В данном уроке мы познакомимся со строковым оператором форматирования.
А какие бывают?
Сперва, в Пайтоне был строковый оператор форматирования, который имитировал функцию printf из языка C, на котором, как известно, написан сам Питон. Затем, в версии Пайтона 3.0 появился строковый метод format(), обладающий более широким и гибким синтаксисом. Но этот способ оказался самым медленным. Позже, в версии 3.6 были созданы f-Строки (PEP 498). Главная их задача — встраивать выражения в строковые литералы с использованием минимального синтаксиса. Скорость же здесь на высоте. Кроме того, в стандартной библиотеке, в модуле string есть класс Template, реализующий более простой способ форматирования строк. Если взять за 100% продолжительность работы самого медленного способа (метод format()), то получится примерно следующее распределение скоростей:
- Строковый оператор форматирования – 82%
- Метод format() – 100%
- f-Строки – 47%
Синтаксис
Строки в Python содержат уникальную встроенную операцию, доступ к которой можно получить через оператор %. Оператор % по отношению к строкам выполняет операцию форматирования и вставки таким образом, что объект, стоящий справа от него, встраивается согласно определенным правилам в строку слева от него. Если вы когда-либо работали с функцией printf в С, вы сразу узнаете, как это работает. Вот простой пример:
print('2 * 2 = %s' % (2 * 2))
# Вывод:
2 * 2 = 4
Ну и давайте сразу о неприятном. Не всегда поведение этого оператора очевидно:
print('2 * 2 = %s' % 2 * 2)
# Вывод:
2 * 2 = 22 * 2 = 2
Как уже говорилось выше, данный способ форматирования пришёл в Питон из языка C, а именно, является прямым заимствованием функции printf(). Конечно, сейчас уже есть более удобные и быстрые методы форматирования, однако в некоторых ситуациях использование оператора % может быть удобнее, чем использование строкового метода format(). Кроме того, полезно знать об этом способе при чтении старых программ.
Важно понимать, что форматируются сами строки, а не вывод, как в случае с функцией print(). На вывод передается уже сформированная строка.
Задаём точность чисел с дробной частью
Оператор деления / возвращает вещественное число. Если количество знаков бесконечно, то Python выведет его в таком виде:
print('5 / 3 =', 5 / 3)
# Вывод:
5 / 3 = 1.6666666666666667
Обычно требуется лишь определенное количество знаков. Для этого в строку записывают комбинацию символов, начинающуюся с %. Число после точки обозначает количество знаков после запятой. Символ f обозначает вещественный тип данных float.
print('4 / 7 =', 4 / 7)
print("%.3f" % (4 / 7))
# Вывод:
4 / 7 = 0.5714285714285714
0.571
Ставить скобки обязательно, иначе операция % выполняется раньше /:
print("%.3f" % 4 / 7)
# Вывод:
Traceback (most recent call last):
File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\scratch.py", line 1, in
print("%.3f" % 4 / 7)
TypeError: unsupported operand type(s) for /: 'str' and 'int'
Process finished with exit code 1
Оператор форматирования строк выполняет округление, а не урезание:
print('Округляем 0.000005:', "%.5f" % (0.000005))
print('Округляем 0.000004:', "%.5f" % (0.000004))
# Вывод:
Округляем 0.000005: 0.00001
Округляем 0.000004: 0.00000
Вывод символа по номеру
from random import randint
[print("%c" % randint(0, 9999), end=' ') for _ in range(10)]
# Вывод:
ऍ ⍥ ನ ᇎ ᠏ ᖹ ڹ ⍠ එ
Вывод целочисленных значений
Если вместо символа ‘c’ использовать ‘d’, будет вставлено само целое число:
from random import randint
[print("%d" % randint(0, 9999), end=' ') for _ in range(10)]
# Вывод:
4113 1363 4474 1265 6116 6726 273 6761 2074 9782
Вставка в строку значений через ключ словаря
print('%(15)s, %(второй).5f' % {'15': 'ХХ', 'второй': 0.5**1.12})
# Вывод:
ХХ, 0.46009
Вывод данных в поля заданной ширины
Бывает данные на экран надо вывести не через один пробел, а в виде таблицы. Другими словами, в полях определенной ширина, где ширина измеряется в знакоместах.
Рассмотрим пример. Допустим надо вывести числа второй строки под числами первой. Если выполнить функцию print() так:
print(10, 235)
print(1000, 50)
# Вывод:
10 235
1000 50
Чтобы привести вывод к табличному виду, необходимо задать ширину поля:
print("%5d%7d" % (10, 235))
print("%5d%7d" % (1000, 50))
# Вывод:
10 235
1000 50
Здесь в кавычках указаны форматы данных и ширина полей. После знака % за кавычками указаны данные, которые будут подставлены вместо каждого указанного формата. Если количество форматов не совпадает с количеством данных, возникнет ошибка.
Форматы данных могут быть: d — целое число, s — строка, f — вещественное число, c — символ.
По умолчанию данные выравниваются по правому краю поля. Чтобы выровнять их по левому, достаточно поставить знак минус перед числом, обозначающим ширину поля. Пример:
print("%-5d%7d" % (10, 235))
print("%-5d%7d" % (1000, 50))
# Вывод:
10 235
1000 50
Список модификаторов формата
Флаги преобразования:
Флаг | Значение |
‘#’ | Для преобразования стоимости будет использоваться «альтернативная форма» (как определено ниже). |
‘0’ | Преобразование будет дополнено нулями для числовых значений. |
‘-‘ | Преобразованное значение остается скорректированным (отменяет ‘0’ преобразование, если указаны оба значения). |
‘ ‘ | (пробел) Перед положительным числом (или пустой строкой), полученным в результате преобразования со знаком, следует оставить пробел. |
‘+’ | Знак ( ‘+’или ‘-‘) будет предшествовать преобразованию (отменяет флаг «пробел»). |
Типы конверсии:
Преобразование | Значение |
‘d’ | Знаковое целое десятичное число. |
‘i’ | Знаковое целое десятичное число. |
‘o’ | Знаковое восьмеричное число. |
‘u’ | Устаревший тип — идентичен ‘d’. |
‘x’ | Знаковое шестнадцатеричное (строчные). |
‘X’ | Знаковое шестнадцатеричное (прописное). |
‘e’ | Экспоненциальный формат с плавающей запятой (нижний регистр). |
‘E’ | Экспоненциальный формат с плавающей точкой (верхний регистр). |
‘f’ | Десятичный формат с плавающей запятой. |
‘F’ | Десятичный формат с плавающей запятой. |
‘g’ | Формат с плавающей запятой. Использует экспоненциальный формат в нижнем регистре, если показатель меньше -4 или не меньше точности, в противном случае — десятичный формат. |
‘G’ | Формат с плавающей запятой. Использует экспоненциальный формат в верхнем регистре, если показатель меньше -4 или не меньше точности, в противном случае — десятичный формат. |
‘c’ | Одиночный символ (принимает целочисленную или односимвольную строку). |
‘r’ | String (преобразует любой объект Python с помощью repr()). |
‘s’ | String (преобразует любой объект Python с помощью str()). |
‘a’ | String (преобразует любой объект Python с помощью ascii()). |
‘%’ | Никакой аргумент не преобразуется, в результате появляется ‘%’ символ. |