I ran into an issue last week where a financial report I was generating had numbers like 1234567.89 printed without any spacing. My manager squinted at the screen for ten seconds before asking if that was a million or a billion. I fixed it with Python’s float formatting, and I have not looked back since.

Formatting floating point numbers comes up all the time in data science scripts, financial dashboards, and any tool that prints numbers for humans to read. Python gives you several ways to do it, and I will walk through each one in this article. By the end you will know how to control decimal places, add thousand separators, and align numbers in tables.

TLDR

  • Use f-strings for the cleanest syntax: f"{value:.2f}"
  • Use format() when you need a string without an f-string: format(value, ",.2f")
  • Use the % operator for old-style formatting: "%.2f" % value
  • Use Decimal from the decimal module for exact decimal arithmetic

What is float formatting in Python?

Float formatting in Python is the process of converting a floating point number to a string with specific rules about decimal places, thousand separators, and alignment. Python supports three main formatting systems: f-strings (introduced in Python 3.6), the format() builtin, and the legacy % operator. All three produce the same result, but f-strings are the most readable.

Formatting with f-strings

F-strings let you embed expressions directly inside string literals with a readable f prefix. The formatting spec goes after a colon inside the curly braces. To fix the decimal places issue I ran into, I would use a spec like :.2f where .2 means two decimal places and f means fixed-point notation, much like the datetime module handles dates.


price = 1234567.89123
print(f"Price: {price:.2f}")
print(f"Price with comma: {price:,.2f}")
print(f"Price with sign: {price:+,.2f}")


Price: 1234567.89
Price with comma: 1,234,567.89
Price with sign: +1,234,567.89

The , in the format spec adds thousand separators automatically. The + forces a sign to appear for positive numbers too. These two tricks alone solved my report problem in about thirty seconds.

Formatting with the format() function

The format() function works the same way as f-strings but without embedding the expression in the string. I use it when I need to format a value inside a larger expression or pass the format spec as a variable.


value = 99.956
formatted = format(value, ".1f")
print(formatted)

One thing I like about format() is that it works with the format spec in a separate argument, which makes it useful when building formatting utilities or templates.

Formatting with the % operator

The % operator is the oldest formatting method in Python, inherited from C. It still works, and you will see it in older codebases, but f-strings are easier to read. The syntax is "%width.precisiontype" % value where width is the total character width and precision is the number of decimal places.


numbers = [5.6, 105.0, 0.059]
for n in numbers:
    print("%6.2f" % n)

The 6.2f spec means a total width of 6 characters with 2 decimal places. Python pads the left side with spaces so all decimal points line up vertically, which is exactly what I needed for that financial report.

Using the Decimal module for exact arithmetic

The regular Python float uses binary floating point, which means some decimal values cannot be represented exactly. For financial calculations where rounding errors are unacceptable, Python provides the decimal module. I reach for this when I am doing money-related math.


from decimal import Decimal, getcontext

getcontext().prec = 6
price = Decimal("0.1") + Decimal("0.2")
print(price)
print(f"{price:.2f}")

Note that I initialized the Decimal with a string, not a float. Passing Decimal(0.1) would carry over the binary floating point error. Using strings as input to Decimal is the reliable pattern for financial work.

Common formatting specs

Here is a quick reference for the format specs I use most often. The general pattern is [fill][align][sign][#,pace][width][,][.precision][type].

value = 42.567

# Two decimal places
print(f"{value:.2f}")

# Thousand separators, 2 decimal places
print(f"{value:,.2f}")

# Zero-padded, 2 decimal places
print(f"{value:010.2f}")

# Right-aligned in 8 chars, 2 decimal places
print(f"{value:>8.2f}")

# Left-aligned in 8 chars, 2 decimal places
print(f"{value:<8.2f}")

# Center-aligned in 8 chars, 2 decimal places
print(f"{value:^8.2f}")

42.57
42.57
0000042.57
   42.57
42.57
  42.57

The 0 padding spec is handy for generating report files where numbers need to line up in fixed-width columns.

FAQ

Q: What is the difference between f-string and format()?

F-strings and format() produce identical output. F-strings are more readable because the expression sits directly inside the string. format() is useful when the format spec needs to be a variable or when working with versions of Python older than 3.6.

Q: Why does 0.1 + 0.2 not equal 0.3 in Python?

This is a known limitation of binary floating point. The values 0.1 and 0.2 cannot be represented exactly in binary, so their sum is approximately but not exactly 0.3. For exact decimal arithmetic, use the Decimal module.

Q: Should I use f-strings or % formatting?

F-strings are preferred for new code. They are easier to read, less error-prone, and slightly faster. The % operator is fine for reading older code but is considered legacy for new projects.

I use f-strings for everything now. The thirty seconds I spend writing f"{value:,.2f}" saves my manager ten seconds of squinting at unformatted numbers. That trade is worth it every time.

Share.
Leave A Reply