Understanding width and precision in Python string formatting

Learn how width and precision works in Python string formatting.

Understanding width and precision in Python string formatting
Understanding how Width and Precision works in Python

Pre-requisite

String Formatting in Python - The Definite Guide
Learn different ways to format strings in Python and test for the fastest method.
Pre-requisite for understanding width and precision

Table of Contents

  1. Begin with a Question
  2. What is 4 divided by 3?
  3. What does 0.3f mean?
  4. Understanding width and precision in Python
  5. Using width and precision with integers
  6. Using width and precision with strings
  7. How to align your strings left and right?

A simple question

Run the following lines of code in your editor and check the output.

Figure out, why are they being printed that way.

print(f"4 divided by 3 is {4/3:0.2f}")
print(f"4 divided by 3 is {4/3:1.2f}")
print(f"4 divided by 3 is {4/3:2.2f}")
print(f"4 divided by 3 is {4/3:3.2f}")
print(f"4 divided by 3 is {4/3:4.2f}")
print(f"4 divided by 3 is {4/3:5.2f}")
print(f"4 divided by 3 is {4/3:6.2f}")
print(f"4 divided by 3 is {4/3:7.2f}")
print(f"4 divided by 3 is {4/3:8.2f}")
print(f"4 divided by 3 is {4/3:9.2f}")
print(f"4 divided by 3 is {4/3:10.2f}")

The answer lies in the width and precision of string formatting.

If you have learned C, C++, or Bash, you would be familiar with the printf function. It is used for printing formatted data to stdout.

Question - Does Python have something similar to printf?

Answer - Not really. Python only provides the print function.

However, you can mimic the behavior of printf by using string formatting.

This is where terms like width and precision come into play.

In this article, you will learn the intricacies of using width and precision with string formatting by comparing 3 different ways of string formatting.

  1. % operator
  2. format method
  3. f-strings

What is 4 divided by 3?

Let’s print the floating-point representation of 4 divided by 3.

Code

# Using % operator
print("%f"%(4/3))

# Using format method
print("{:f}".format(4/3))

# Using f-strings
print(f"{4/3:f}")

Output

1.333333
1.333333
1.333333

Each of the above formatting methods, produces the same output. The output of 4 divided by 3 has 6 digits after the decimal.

Let’s try to limit the number of decimal places to 3.

Code

# Using % operator
print("%0.3f"%(4/3))

# Using format method
print("{:0.3f}".format(4/3))

# Using f-strings
print(f"{4/3:0.3f}")

Output

1.333
1.333
1.333

By using 0.3f as format placeholders, we are able to contain the number of decimal places to 3.


Understanding the structure of 0.3f

Let’s generalize 0.3f into a formula - x.yf

  1. x represents the minimum width or padding of the output string.
  2. y represents the maximum number of characters after the decimal.
  3. f symbolizes floating-point representation.

Let’s alter the x and y values and see how the output changes.

Code

# Using % operator
print("%10.2f"%(4/3))

# Using format method
print("{:10.2f}".format(4/3))

# Using f-strings
print(f"{4/3:10.2f}")

Output

      1.33
      1.33
      1.33

You can see that your result contains empty white spaces to the left of each output.

So what happened? Let’s dive in.


Understanding width and precision in Python

Stage 1 - Using only %f representation

If you just use %f representation, the output will have a width/length of 8.

Code

# Using % operator
print("%f"%(4/3))

# Using format method
print("{:f}".format(4/3))

# Using f-strings
print(f"{4/3:f}")

Output

1.333333
1.333333
1.333333
Formatting width and precision in Python strings

Stage 2 - Adding width

Let’s add only a width placeholder to %f.

Code

# Using % operator
print("%10f"%(4/3))

# Using format method
print("{:10f}".format(4/3))

# Using f-strings
print(f"{4/3:10f}")

When the user-defined width is different(greater or smaller) than the original width, the length of the output is changed to the user-defined width. In the above example, the new length of output will be 10 characters long.

Output

  1.333333
  1.333333
  1.333333

The resulting output is now right-aligned with extra 2 white space characters added as padding to the left.

Adding extra width to string formating in Python

However, if the user-defined width is 0, the original length of the output is maintained.

Try providing the width as 0. 0f will provide the same result as using f floating-point representation.

Code

# Using % operator
print("%0f"%(4/3))

# Using format method
print("{:0f}".format(4/3))

# Using f-strings
print(f"{4/3:0f}")

Output

1.333333
1.333333
1.333333

Stage 3 - Adding precision

Let’s now change the number of decimal places in the output to 2. This can be done by providing the precision value.

Code

# Using % operator
print("%10.2f"%(4/3))

# Using format method
print("{:10.2f}".format(4/3))

# Using f-strings
print(f"{4/3:10.2f}")

Upon fixing the precision to 2, the resulting output will only have 2 characters after the decimal. All the other characters after the 2nd decimal places are chopped off.

Hence, the output string moves even further to the right, creating more empty white spaces.

Output

      1.33
      1.33
      1.33
Fix the precision of string formatting in Python

Using width and precision with integers

Formatting integers with the Width

Formatting integers with width has a similar effect as formatting floating points.

Code

# Using % operator
print("%10d"%(1992))

# Using format method
print("{:10d}".format(1992))

# Using f-strings
print(f"{1992:10d}")

Output

      1992
      1992
      1992
Adding width to integer formatting in Python

Formatting integers with precision

However, providing precision with % formatting has no effect and with f-strings and format method, it throws an error.

Code/Output - precision with % operator

# Using % operator
print("%10.2d"%(1992))
>>>       1992

Code/Output - precision with format and f-strings

# Using format method
print("{:10.2d}".format(1992))

>>>Traceback (most recent call last):
     File "some_file_location", line 5, in <module>
       print("{:10.2d}".format(1992))
   ValueError: Precision not allowed in integer format specifier

# Using f-strings
print(f"{1992:10.2d}")

>>>Traceback (most recent call last):
     File "some_file_location", line 8, in <module>
       print(f"{1992:10.2d}")
   ValueError: Precision not allowed in integer format specifier

Using width and precision with strings

Formatting string with Width

Unfortunately, the default alignment differs between % formatting (old style) and formatting with format method and f-strings (new style).

The old-style defaults to right-aligned while for new style it’s left.

Code

# Using % operator
print("%10s"%("Pylenin"))

# Using format method
print("{:10s}".format("Pylenin"))

# Using f-strings
print(f"{'Pylenin':10s}")

Output

   Pylenin
Pylenin   
Pylenin   
String formatting with width in Python

You can change this behavior easily by using certain operators.


How to align your strings left and right?

To right-align your string, use > operator with the new formatting methods.

Code - To right align strings

# Using % operator
print("%10s"%("Pylenin"))

# Using format method
print("{:>10s}".format("Pylenin"))

# Using f-strings
print(f"{'Pylenin':>10s}")

Output

   Pylenin
   Pylenin
   Pylenin

To left-align your string, use - operator with the old formatting method.

Code - To left-align strings

# Using % operator
print("%-10s"%("Pylenin"))

# Using format method
print("{:10s}".format("Pylenin"))

# Using f-strings
print(f"{'Pylenin':10s}")

Output

Pylenin   
Pylenin   
Pylenin   

Formatting string with precision

When you add precision to string formatting, the characters of the string are truncated.

Let’s say, you provide a precision of n. All the characters except the first n characters are truncated.

Code

# Using % operator
print("%10.2s"%("Pylenin"))

# Using format method
print("{:10.2s}".format("Pylenin"))

# Using f-strings
print(f"{'Pylenin':10.2s}")

Output

        Py
Py        
Py           
Formatting string with precision in Python

Subscribe to Pylenin

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe