Python - Python String Formatting with f-Strings and Format Specifications

String formatting is the process of inserting values into a string and controlling how those values are displayed. Python provides several ways to format strings, including the older % operator, the str.format() method, and the modern f-string approach. F-strings were introduced in Python 3.6 and provide a concise and readable way to combine text with variables and expressions.

1. What Are f-Strings?

An f-string is a string prefixed with the letter f or F. Variables and expressions can be placed inside curly braces {}.

name = "Rahul"
age = 25

message = f"My name is {name} and I am {age} years old."
print(message)

Output:

My name is Rahul and I am 25 years old.

Python evaluates the expressions inside {} and replaces them with their resulting values.

2. Inserting Expressions

F-strings are not limited to simple variables. They can contain Python expressions.

a = 10
b = 20

print(f"The sum is {a + b}")

Output:

The sum is 30

You can also call functions inside an f-string.

name = "python"

print(f"Language: {name.upper()}")

Output:

Language: PYTHON

This makes f-strings useful when the value needs to be calculated or transformed before being displayed.

3. Formatting Decimal Numbers

F-strings allow you to control the number of decimal places displayed using a format specification.

For example:

price = 125.67894

print(f"Price: {price:.2f}")

Output:

Price: 125.68

Here, .2f means that the number should be displayed as a floating-point value with exactly two digits after the decimal point.

Similarly:

value = 45.98765

print(f"{value:.1f}")
print(f"{value:.3f}")

Output:

46.0
45.988

The number after the decimal point determines the required precision.

4. Formatting Percentages

F-strings can directly format decimal values as percentages using %.

completion = 0.875

print(f"Completion: {completion:.1%}")

Output:

Completion: 87.5%

The % format multiplies the value by 100 and adds the percentage symbol.

For example:

tax = 0.18

print(f"Tax rate: {tax:.0%}")

Output:

Tax rate: 18%

5. Formatting Currency Values

F-strings can be used to display monetary values neatly.

amount = 12500.5

print(f"Amount: ₹{amount:,.2f}")

Output:

Amount: ₹12,500.50

The comma adds thousands separators, while .2f ensures two decimal places.

Another example:

salary = 750000

print(f"Annual salary: ₹{salary:,}")

Output:

Annual salary: ₹750,000

The formatting itself does not perform currency conversion. It only controls how the number is displayed.

6. Alignment of Text

F-strings provide formatting options for aligning text within a specified width.

Left alignment uses <:

name = "Python"

print(f"{name:<15}")

The text occupies a field of 15 characters and is aligned to the left.

Right alignment uses >:

print(f"{name:>15}")

Center alignment uses ^:

print(f"{name:^15}")

These features are useful when creating simple reports or tabular console output.

For example:

print(f"{'Name':<15}{'Age':>5}")
print(f"{'Rahul':<15}{25:>5}")
print(f"{'Priya':<15}{22:>5}")

Output:

Name              Age
Rahul              25
Priya              22

7. Adding Padding Characters

You can specify a character to fill the unused space.

name = "Python"

print(f"{name:*^20}")

Output:

*******Python*******

Here:

  • 20 specifies the total width.

  • ^ specifies center alignment.

  • * specifies the padding character.

Another example:

number = 42

print(f"{number:0>5}")

Output:

00042

This technique is often useful for displaying identifiers, numbers, or codes with a fixed width.

8. Formatting Integers in Different Number Systems

F-strings can represent integers using different bases.

Binary representation:

number = 10

print(f"Binary: {number:b}")

Output:

Binary: 1010

Octal representation:

print(f"Octal: {number:o}")

Output:

Octal: 12

Hexadecimal representation:

print(f"Hexadecimal: {number:x}")

Output:

Hexadecimal: a

Uppercase hexadecimal can be obtained with X.

print(f"Hexadecimal: {number:X}")

Output:

Hexadecimal: A

These formats can be useful in programming tasks involving binary data, memory addresses, colors, and low-level representations.

9. Scientific Notation

Very large or very small numbers can be represented using scientific notation.

distance = 150000000

print(f"{distance:.2e}")

Output:

1.50e+08

The e format displays the number using scientific notation. The .2 specifies two digits after the decimal point.

10. Formatting Numbers with Underscores

Python allows underscores to improve the readability of large numbers.

number = 1000000000

print(f"{number:_}")

Output:

1_000_000_000

This can make large values easier to read, particularly when working with financial or scientific data.

11. Using Variables Inside Format Specifications

Format specifications themselves can be controlled dynamically.

number = 45.6789
precision = 2

print(f"{number:.{precision}f}")

Output:

45.68

Here, precision determines how many digits appear after the decimal point.

Similarly, width can be controlled using another variable:

name = "Python"
width = 15

print(f"{name:>{width}}")

Output:

         Python

This is useful when the required formatting depends on user input or program conditions.

12. Formatting Dates and Times

F-strings can also be combined with datetime objects.

from datetime import datetime

today = datetime.now()

print(f"Date: {today:%d-%m-%Y}")
print(f"Time: {today:%H:%M:%S}")

A possible output is:

Date: 23-09-2026
Time: 14:35:20

The formatting codes determine how the date and time are displayed.

For example:

  • %d represents the day.

  • %m represents the month.

  • %Y represents the four-digit year.

  • %H represents the hour.

  • %M represents minutes.

  • %S represents seconds.

13. Debugging with f-Strings

Python also provides a useful debugging feature called the self-documenting expression.

name = "Rahul"
age = 25

print(f"{name=}, {age=}")

Output:

name='Rahul', age=25

Instead of displaying only the values, Python displays both the variable names and their values.

Expressions can also be used:

a = 10
b = 20

print(f"{a + b=}")

Output:

a + b=30

This feature can be particularly helpful when debugging programs.

14. Calling Methods in f-Strings

Methods can be called directly inside the curly braces.

name = "rahul"

print(f"Name: {name.title()}")

Output:

Name: Rahul

Another example:

text = "python programming"

print(f"{text.upper()}")

Output:

PYTHON PROGRAMMING

However, complicated expressions should generally be calculated separately when doing so improves readability.

15. Formatting Boolean Values

Boolean values can also be inserted into strings.

is_logged_in = True

print(f"User logged in: {is_logged_in}")

Output:

User logged in: True

You can also use conditional expressions:

age = 20

print(f"Status: {'Adult' if age >= 18 else 'Minor'}")

Output:

Status: Adult

16. Using f-Strings with Objects

F-strings work with objects as well.

class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

student = Student("Anita", 92)

print(f"Student: {student.name}, Marks: {student.marks}")

Output:

Student: Anita, Marks: 92

This is useful when displaying information stored inside class objects.

17. Format Specification Structure

A basic f-string expression follows this structure:

f"{expression:format_specification}"

For example:

price = 1234.567

print(f"{price:,.2f}")

Here:

  • price is the expression.

  • : separates the expression from the format specification.

  • , adds a thousands separator.

  • .2 specifies two decimal places.

  • f indicates floating-point formatting.

Understanding this structure makes it easier to construct complex formatting patterns.

18. Advantages of f-Strings

F-strings provide several advantages over older string-formatting techniques.

They are generally easier to read because variables appear directly inside the string.

name = "Anita"
score = 95

print(f"{name} scored {score} marks.")

They can evaluate expressions directly.

print(f"Total: {10 + 20}")

They provide powerful formatting options.

price = 4567.891

print(f"₹{price:,.2f}")

They also reduce the amount of code required compared with some older formatting approaches.

19. Important Precautions

Although f-strings are convenient, expressions inside them should remain reasonably simple.

For example:

name = "Rahul"
age = 25

message = f"{name} is {age} years old."

is easier to understand than placing a large amount of processing directly inside the string.

Another important consideration is security. F-strings evaluate Python expressions that are written directly into the source code. They should not be confused with a mechanism for safely evaluating arbitrary user-provided Python code.

20. Example: Creating a Student Report

The following example combines several formatting techniques:

name = "Anita"
marks = 92
percentage = 92.4567
fees = 12500

print(f"{'Student Report':^30}")
print(f"{'Name':<15}: {name}")
print(f"{'Marks':<15}: {marks}")
print(f"{'Percentage':<15}: {percentage:.2f}%")
print(f"{'Fees':<15}: ₹{fees:,.2f}")

Output:

        Student Report
Name           : Anita
Marks          : 92
Percentage     : 92.46%
Fees           : ₹12,500.00

This demonstrates how f-strings can be used to create clean and structured output.

Conclusion

Python f-strings provide a modern and flexible way to construct formatted strings. They allow variables, expressions, function calls, calculations, alignment, padding, decimal precision, percentages, currency-style numbers, different number bases, dates, and debugging expressions to be incorporated directly into strings. The general pattern is f"{expression:format_specification}", where the format specification determines how the resulting value is displayed. Because of their readability and flexibility, f-strings are widely useful for reports, console output, logging messages, user-facing text, and debugging Python programs.