# Formatting numbers in Python

By John Lekberg on June 27, 2020.

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

• How to control alignment.
• How to format numbers as binary and hexadecimal.
• How to add grouping to large numbers (e.g. "1,000,000" instead of "1000000").

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:

• Be 3 digits wide. (Whitespace is added if needed.)
• Be aligned to the right.
``````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

• Makes the minimum width `8` characters.
• Fills in the extra space with `0` (instead of whitespace).
``````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:

• Exponent notation (e.g. `2 ** 30` becomes `1.073742e+09`).
• Percentages (e.g. `.32` becomes `32%`).

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"]
``````

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!

(If you spot any errors or typos on this post, contact me via my contact page.)