LearnContact
Lesson 1426 min read

String Formatting (f-Strings)

Master f-strings for building dynamic text in Python, including expressions, format specifiers, alignment, and a look at older formatting styles.

Introduction

So far you have built text by concatenating strings with +, which becomes clunky once you are mixing several variables and different data types. Python solves this with f-strings — short for "formatted string literals" — a clean, readable way to embed values directly inside text.

This lesson takes a deep dive into f-strings: embedding expressions, calling functions inside them, formatting numbers precisely, and aligning text. You will also briefly see the two older formatting styles so you can recognize them in existing code.

What You Will Learn
  • How to build f-strings and embed variables and expressions.
  • How to call methods and functions directly inside {}.
  • How to format decimals and add thousands separators.
  • How to align and pad text using format specifiers.
  • How the older .format() method and % formatting work.
  • Why f-strings are the recommended modern approach.

What is an f-String?

An f-string is a regular string literal prefixed with the letter f. Inside the string, anything wrapped in curly braces {} is treated as Python code and evaluated, then automatically converted to text and inserted into the string.

name = "Amol"
age = 22

print(f"My name is {name} and I am {age} years old.")
Output
My name is Amol and I am 22 years old.
The f Prefix Is Required

Without the f prefix, curly braces are treated as literal text — "My name is {name}" would print exactly that, braces and all, instead of substituting the variable.

Embedding Expressions

The curly braces in an f-string are not limited to plain variables — you can place any valid Python expression inside them, including arithmetic, comparisons, and conditional expressions.

price = 250
quantity = 3

print(f"Total: {price * quantity}")
print(f"Is expensive: {price > 200}")

score = 82
print(f"Result: {'Pass' if score >= 40 else 'Fail'}")
Output
Total: 750
Is expensive: True
Result: Pass

Calling Methods and Functions Inside {}

Because the braces accept any expression, you can call string methods or your own functions directly inside an f-string, without needing a separate variable.

name = "  python  "
print(f"Cleaned name: {name.strip().title()}")

def square(n):
    return n * n

number = 6
print(f"{number} squared is {square(number)}")
Output
Cleaned name: Python
6 squared is 36

Format Specifiers for Numbers

A format specifier goes after a colon inside the braces and controls exactly how a value is displayed. The most common one is .Nf, which rounds a floating-point number to N decimal places.

pi = 3.14159265
price = 49.9

print(f"Pi rounded: {pi:.2f}")
print(f"Price: {price:.2f}")
print(f"Whole number: {pi:.0f}")
Output
Pi rounded: 3.14
Price: 49.90
Whole number: 3
Percentages Too

The % specifier multiplies by 100 and appends a percent sign, so f"{0.256:.1%}" produces "25.6%" — handy for displaying ratios.

Thousands Separators

Adding a comma inside the format specifier automatically inserts thousands separators, which is useful for displaying large numbers like currency amounts or population figures.

population = 1400000000
salary = 1234567.891

print(f"Population: {population:,}")
print(f"Salary: {salary:,.2f}")
Output
Population: 1,400,000,000
Salary: 1,234,567.89

Alignment and Padding

You can control the width of a formatted value and how it is aligned within that width — left, right, or centered — which is especially useful for lining up columns of text.

SpecifierMeaning
{value:<10}Left-align within 10 characters
{value:>10}Right-align within 10 characters
{value:^10}Center within 10 characters
{value:*>10}Right-align, padding with * instead of spaces
items = [("Apple", 3), ("Banana", 12), ("Fig", 150)]

for name, qty in items:
    print(f"{name:<10}{qty:>5}")
Output
Apple         3
Banana       12
Fig         150
print(f"{'PYTHON':^20}")
print(f"{'PYTHON':*^20}")
Output
       PYTHON        
*******PYTHON*******

The Older .format() Method

Before f-strings were introduced in Python 3.6, the str.format() method was the standard way to build formatted text. It uses {} placeholders in the string and passes values as arguments to .format().

name = "Amol"
age = 22

print("My name is {} and I am {} years old.".format(name, age))
print("My name is {0} and I am {1} years old. Hi {0}!".format(name, age))
Output
My name is Amol and I am 22 years old.
My name is Amol and I am 22 years old. Hi Amol!

You will still encounter .format() in older codebases and some libraries, so it is worth being able to read it, even though you are unlikely to choose it for new code.

The Even Older % Formatting

Before .format() existed, Python borrowed a formatting style from the C language using the % operator with placeholders like %s for strings and %d for integers.

name = "Amol"
age = 22

print("My name is %s and I am %d years old." % (name, age))
Output
My name is Amol and I am 22 years old.
For Recognition Only

% formatting is largely considered legacy Python. You may see it in very old code or documentation, but it is not recommended for anything you write today.

Why f-Strings Are the Modern Choice

f-strings became the recommended way to format text in Python because they are shorter, faster, and easier to read than the alternatives — the variable appears directly where its value will be inserted, instead of in a separate list of arguments.

f-strings

  • Values appear right where they are used.
  • Supports full expressions, not just variables.
  • Generally the fastest formatting option.
  • Introduced in Python 3.6 and considered the standard today.

.format() and %

  • Values are separated from their placeholders, harder to read.
  • .format() is more verbose for simple cases.
  • % formatting has confusing rules for non-string types.
  • Still found in older code, so worth recognizing.

Common Mistakes

Avoid These Mistakes
  • Forgetting the f prefix and ending up with literal curly braces in the output.
  • Using single quotes for the f-string and the expression inside it in the same style, causing a syntax error, for example f'{"a".upper()}' needs mismatched quote types in older Python versions.
  • Mixing up : (format specifier) with = (debug specifier) when reading unfamiliar f-string code.
  • Forgetting the comma in {value:,} and wondering why big numbers are not separated.
  • Assuming .format() and % formatting are required knowledge for writing new code — they are mainly for recognition.

Best Practices

  • Use f-strings for essentially all new string formatting in Python.
  • Use :.2f for currency and measurements that need a fixed number of decimals.
  • Use :, or :,.2f whenever displaying large numbers to a human reader.
  • Use alignment specifiers to keep printed tables and reports neatly lined up.
  • Keep expressions inside {} simple and readable — extract complex logic into a variable first if needed.

Frequently Asked Questions

What Python version do I need for f-strings?

f-strings were introduced in Python 3.6, so any modern Python 3 installation supports them.

Can I use an f-string without any curly braces?

Yes, though it behaves just like a normal string in that case — the f prefix only matters when {} placeholders are present.

How do I show a literal curly brace in an f-string?

Double it up: f"{{literal braces}}" outputs {literal braces}.

Should I still learn .format() and %?

You do not need to use them in new code, but recognizing them helps you read older Python code and some library documentation.

Can format specifiers be combined, like alignment and decimals together?

Yes, for example f"{value:>10.2f}" right-aligns a number within 10 characters while rounding it to two decimal places.

Key Takeaways

  • f-strings are prefixed with f and embed expressions directly inside {}.
  • You can call methods and functions inside f-string braces.
  • Format specifiers after a colon control decimals, thousands separators, and alignment.
  • .format() and % formatting are older styles still found in existing code.
  • f-strings are the modern, recommended way to format strings in Python.

Summary

f-strings give you a concise, readable, and powerful way to build dynamic text by embedding expressions and controlling exactly how values are displayed. You also now recognize the older .format() and % styles when you encounter them in existing code.

With strings, string methods, and formatting covered, you are ready to move on to Python's most commonly used data structure for storing collections of items: the list.

Lesson 14 Completed
  • You can embed variables, expressions, and function calls inside f-strings.
  • You can format decimals, thousands separators, and alignment precisely.
  • You can recognize the older .format() and % formatting styles.
  • You are ready to start working with lists.
Next Lesson →

Lists