String formatting operator – Operator %

by Alex
String formatting operator - Operator %

Despite one of the Python principles that says, “There must be one – and preferably only one – obvious way to do something,” our beloved language has as many as four ways to format a string. That’s how it’s historically been done. This is the first lesson in a series on string formatting. It includes:

  1. String format statement
  2. Format() method
  3. f-Lines
  4. Template strings

In this lesson, we will be introduced to the string formatting operator.

What are they?

First, Python had a string format statement that mimicked the printf function from the C language in which Python itself is known to be written. Then, Python 3.0 introduced the format() string method, which has a wider and more flexible syntax. But this method turned out to be the slowest. Later, in version 3.6, f-Lines were created (PEP 498). Their main task is to embed expressions in string literals using the minimal syntax. The speed here is at an all-time high. In addition, in the standard library, in the module string, there is a class Template, which implements a more simple way to format strings. If we take as 100% the duration of the slowest way (method format()), then we get approximately the following speed distribution:

  • String format statement – 82%
  • Format() method – 100%
  • f-Lines – 47%


Strings in Python contain a unique built-in operation, which can be accessed through the % operator. The % operator with respect to strings performs a formatting and insertion operation, so that the object to its right is embedded according to certain rules in the string to its left. If you have ever worked with the printf function in C, you will immediately know how it works. Here is a simple example:

print('2 * 2 = %s' % (2 * 2))
# Output:
2 * 2 = 4

Well, let’s get straight to the unpleasant part. The behavior of this operator is not always obvious:

print('2 * 2 = %s' % 2 * 2)
# Output:
2 * 2 = 22 * 2 = 2

As mentioned above, this way of formatting came to Python from the C language, namely, it is a direct borrowing of the printf() function. Of course, there are already more convenient and faster formatting methods available; however, in some situations, using the % operator may be more convenient than using the string format() method. Besides, it is useful to know about this method when reading old programs. It is important to understand that it is the strings themselves that are formatted, not the output, as in the case of the print() function. An already-formatted string is sent to the output.

Setting the precision of numbers with fractions

The division operator / returns a real number. If the number of digits is infinite, Python will output it as such:

print('5 / 3 =', 5 / 3)
# Output:
5 / 3 = 1.6666666666666667

Usually only a certain number of digits is needed. To do this, a combination of characters beginning with % is written into the string. The number after the dot denotes the number of digits after the decimal point. The character f stands for the real data type float.

print("4 / 7 =', 4 / 7)
print("%.3f" % (4 / 7))
# Output:
4 / 7 = 0.5714285714285714

Brackets are obligatory, otherwise the % operation is performed before /:

print("%.3f" % 4 / 7)
# Output:
Traceback (most recent call last):
File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\", line 1, in
print("%.3f" % 4 / 7)
TypeError: unsupported operand type(s) for /: 'str' and 'int'
Process finished with exit code 1

The string formatting operator performs rounding, not truncation:

print('Round by 0.000005:',"%.5f" %(0.000005))
print('Rounding 0.000004:', "%.5f" % (0.000004))
# output:
Round off 0.000005: 0.00001
Rounding 0.000004: 0.00000

Character output by number

from random import randint
[print("%c" % randint(0, 9999), end='') for _ in range(10)]
# Output:
ऍ ⍥ ನ ᇎ ᠏ ᖹ ڹ ⍠ එ

Output integer values

If ‘d’ is used instead of ‘c’, the integer itself will be inserted:

from random import randint
[print("%d" % randint(0, 9999), end='') for _ in range(10)]
# Output:
4113 1363 4474 1265 6116 6726 273 6761 2074 9782

Inserting into a string of values with a dictionary key

print('%(15)s, %(second).5f' % {'15': 'XX', 'second': 0.5**1.12})
# Output:
XX, 0.46009

Data output in the fields of a given width

Sometimes data should not be displayed with a single space, but as a table. In other words, in the fields of a certain width, where the width is measured in sign spaces. Let’s take an example. Suppose we need to print the numbers of the second row under the numbers of the first row. If we execute the print() function like this:

print(10, 235)
print(1000, 50)
# output:
10 235
1000 50

To make the output tabular, we need to set the width of the field:

print("%5d%7d" % (10, 235))
print("%5d%7d" % (1000, 50))
# Output:
10 235
1000 50

Here, the data formats and field widths are specified in quotation marks. After the % sign behind the quotation marks is the data that will be substituted for each specified format. If the number of formats does not match the number of data, an error will occur. The data formats can be: d – integer, s – string, f – real number, c – symbol. By default, the data is aligned on the right side of the field. To align them to the left, simply put a minus sign in front of the number that denotes the width of the field. Example:

print("%-5d%7d" % (10, 235))
print("%-5d%7d" % (1000, 50))
# Output:
10 235
1000 50

List of format modifiers

Conversion flags: Flag Value ‘#’ An ‘alternate form’ (as defined below) will be used for the value conversion. ‘0’ The conversion will be appended with zeros for numeric values. ‘-‘ The converted value will remain corrected (cancels ‘0’ conversion if both values are specified). ‘ ‘ (space) A space should be left before a positive number (or blank line) resulting from the conversion with a sign. ‘+’ The sign (‘+’or ‘-‘) will precede the conversion (cancels the ‘space’ flag). Conversion types: Conversion Value ‘d’ Signed integer decimal number. ‘i’ Signed integer decimal number. ‘o’ Signed octal number. ‘u’ Obsolete type – identical to ‘d’. ‘x’ Signed hexadecimal (lowercase). ‘X’ Signed hexadecimal (lowercase). ‘e’ Exponential format floating point (lower case). ‘E’ Exponential floating point format (upper case). ‘f’ Decimal floating point format. ‘F’ Decimal floating point format. ‘g’ Floating point format. Uses exponential format in lower case if the value is less than -4 or not less than precision, otherwise decimal format. ‘G’ Floating point format. Uses exponential format in uppercase if the value is less than -4 or not less than precision, otherwise decimal format. ‘c’ Single character (takes integer or single-character string). ‘r’ String (converts any Python object with repr()). ‘s’ String (converts any Python object with str()). ‘a’ String (converts any Python object with ascii()). ‘%’ No argument is converted, resulting in a ‘%’ character.

Related Posts