Return to Blog

Formatting numbers in Python

By John Lekberg on June 27, 2020.


This week's post is about formatting numbers in Python. You will learn:


Python can automatically turn numbers into strings:

x = 0.3037385937020861
str(x)
'0.3037385937020861'

But, I'm not always satisfied with the default formatting. I can use the built-in function format to control this.

format(x)
'0.3037385937020861'
format(x, ".2f")
'0.30'
format(x, "%")
'30.373859%'
format(x, ".2%")
'30.37%'

How does format() work?

format(obj, spec)

takes an object obj and formats it according to a specifier spec.

The specifier is fully documented in "Format Specification Mini-Language".


The specifier can control width and alignment. For example, consider printing out this list of numbers:

nums = [1, 10, 13, 2, 43, 2, 3, 100]
for x in nums:
    print(x)
1
10
13
2
43
2
3
100

I use the format specifier ">3" to have each formatted number:

nums = [1, 10, 13, 2, 43, 2, 3, 100]
for x in nums:
    print(format(x, ">3"))
  1
 10
 13
  2
 43
  2
  3
100

The alignment doesn't work right if I pass too small of a width:

nums = [1, 10, 13, 2, 43, 2, 3, 100]
for x in nums:
    print(format(x, ">2"))
 1
10
13
 2
43
 2
 3
100

And if I pass a larger width, then extra whitespace is added as needed:

nums = [1, 10, 13, 2, 43, 2, 3, 100]
for x in nums:
    print(format(x, ">20"))
                   1
                  10
                  13
                   2
                  43
                   2
                   3
                 100

The format specifier can also display numbers as binary, hexadecimal. For example, consider printing out the byte values of this byte string:

msg = b"general kenobi"
for byte in msg:
    print(byte)
103
101
110
101
114
97
108
32
107
101
110
111
98
105

I use the format specifier "b" to see the binary representation of this data:

msg = b"general kenobi"
for byte in msg:
    print(format(byte, "b"))
1100111
1100101
1101110
1100101
1110010
1100001
1101100
100000
1101011
1100101
1101110
1101111
1100010
1101001

I want to show the full 8 bits for each byte (00100000 instead of 100000), so I change the format specifier from "b" to "08b", which

msg = b"general kenobi"
for byte in msg:
    print(format(byte, "08b"))
01100111
01100101
01101110
01100101
01110010
01100001
01101100
00100000
01101011
01100101
01101110
01101111
01100010
01101001

I use the format specifier "x" to see the hexadecimal representation of this data:

msg = b"general kenobi"
for byte in msg:
    print(format(byte, "x"))
67
65
6e
65
72
61
6c
20
6b
65
6e
6f
62
69

Another nice feature of the format specifier is that it can group digits in large numbers. For example, I have 230

n = 2 ** 30
print(n)
1073741824

I use the format specifier "," to place commas as thousands separators:

n = 2 ** 30
print(format(n, ","))
1,073,741,824

I can also use the format specifier "_" to place underscores as the thousands separators:

n = 2 ** 30
print(format(n, "_"))
1_073_741_824

Format specifiers have other features, like:

I highly recommend you read the Python documentations "Format Specification Mini-Language" to learn about all of the different capabilities.


Besides calling the built-in function format(), you can also use str.format() and formatted string literals (also called "f-strings").

Here's an example of using str.format() to format a number into a sentence.

n = 2 ** 25
print("I have ${:,} in student loans.".format(n))
I have $33,554,432 in student loans.

(The format specifier is , inside the replacement field {:,}.) For more information about str.format(), read "Format String Syntax".

Formatted string literals ("f-strings") are similar to format strings, with a few differences. Here's the above example using f-strings:

n = 2 ** 25
print(f"I have ${n:,} in student loans.")
I have $33,554,432 in student loans.

Notice that the string starts with f" (instead of just "), and that the replacement field {n:,} has both the variable n and the format specifier ,. For more information about f-strings, read

In conclusion...

In this week's post, you learned about formatting numbers in Python. You learned how to control alignment, format numbers as binary and hexadecimal, and add grouping to large numbers (e.g. "1,000,000" instead of "1000000").

My challenge to you:

Take this data:

names = ["John", "Bobby", "Hank"]
grades = [.98, .93, .75]

And use string formatting to generate this plain text table:

Student  Grade
-------  -----
John       98%
Bobby      93%
Hank       75%

If you enjoyed this week's post, share it with your friends and stay tuned for next week's post. See you then!