Format Strings in Python

Learn how to format strings in Python using the str.format() method, positional and keyword placeholders, and the format specification mini-language.

5 min read

Format strings in Python let you insert values into text with precise control over how those values appear: how many decimal places a number shows, how wide a column should be, whether text is left-aligned or right-aligned, and how to combine the same value with different formatting in different places within the same output. Before Python had f-strings and the format() method, programmers used percent-formatting with the modulo operator, a syntax inherited from the C language. While that older style still works, the format() method introduced in Python 2.6 and its more concise successor f-strings have become the standard tools for string formatting in modern Python code.

This article focuses on the str.format() method, which uses curly braces as placeholders and provides a rich format specification mini-language that you can apply to numbers, strings, dates, and custom objects. The next article covers Python f-strings, which use the same mini-language but evaluate expressions directly inside the string. Understanding format() first gives you a solid mental model for how the placeholder-and-specifier system works, and that knowledge transfers directly to f-strings and to the format specification mini-language used throughout the Python standard library.

The formatting concepts in this article build on the fundamental string knowledge from earlier in this section. If you are comfortable with creating strings and common string operations like concatenation, you are ready to learn how format() replaces manual string assembly with a cleaner, more declarative approach.

How str.format() replaces placeholders

The format() method is called on a string that contains replacement fields enclosed in curly braces. Python scans the string, finds each set of braces, and replaces them with the corresponding argument passed to format(). If you provide three arguments to format(), the first pair of braces gets the first argument, the second pair gets the second, and so on.

pythonpython
template = "{} is the capital of {}"
result = template.format("Paris", "France")
print(result)  # 'Paris is the capital of France'

When no numbers or names appear inside the braces, Python fills them in order from left to right. This is the simplest form and works well when you have a small number of values and the reading order naturally matches the template order. For more control, you can put numbers inside the braces to specify which positional argument goes where, which is especially useful when the same value needs to appear in multiple places within the same string.

The positional and keyword systems can be mixed within a single format() call. Positional arguments use numbers like {0} and {1}, while keyword arguments use descriptive names like {name} and {total}. When mixing the two, the positional arguments must appear first in the argument list to format(), and the keyword arguments follow. This gives you the flexibility to use numbers for values that change position and names for values that have clear semantic meaning in your application.

The format specification mini-language

The real power of str.format() comes from what you put after a colon inside each replacement field. The colon separates the field name or number from a format specifier, and the specifier controls how the value is displayed. You can specify the number of decimal places for a float, the minimum width of a field in characters, whether the value is aligned to the left or right, and a fill character to use for unused space.

pythonpython
price = 49.95
print("Price: ${:.2f}".format(price))   # 'Price: $49.95'
 
name = "Alice"
print("|{:>10}|".format(name))          # '|     Alice|'
print("|{:<10}|".format(name))          # '|Alice     |'
print("|{:^10}|".format(name))          # '|  Alice   |'

The first example uses .2f to format the price as a fixed-point number with two decimal places. The second set of examples demonstrates field width and alignment: >10 means right-aligned in a field 10 characters wide, <10 means left-aligned, and ^10 centers the value. You can also specify a custom fill character by placing it before the alignment symbol, so {:*>10} produces '*****Alice'.

For integers, the format specifier d handles base-10 display, x and X produce lowercase or uppercase hexadecimal, o produces octal, and b produces binary. Combined with width and zero-padding, these make it easy to display numbers in the exact format your application requires without writing manual conversion code.

The format specification mini-language is used not only by str.format() but also by f-strings and by Python's built-in format() function. Learning it once means you understand formatting across the entire language. The official Python documentation provides a complete reference of every available specifier, but the subset covered in this article handles the vast majority of everyday formatting needs.

Rune AI

Rune AI

Key Insights

  • str.format() replaces curly brace placeholders with values from its arguments in order.
  • Use {0}, {1}, {2} for positional arguments or {name} for keyword arguments.
  • Add a colon and format specifier inside braces to control precision: '{:.2f}'.format(3.14159).
  • Set field width and alignment with '{:>10}' for right-align or '{:<10}' for left-align.
  • F-strings are preferred for inline formatting; use format() when the template is separate from the data.
RunePowered by Rune AI

Frequently Asked Questions

What is the difference between f-strings and the format() method?

Both f-strings and the format() method use the same replacement field syntax with curly braces, but they differ in how values are supplied. F-strings evaluate expressions directly inline at the point where the string is defined, which makes them more concise and slightly faster. The format() method takes values as separate arguments after the string, which is useful when the template and the data are defined in different places or when the same template is reused with different values. Both support the same format specification mini-language for controlling precision, alignment, and padding.

How do I control decimal places when formatting numbers?

Use a format specifier after a colon inside the replacement field. For example, '{:.2f}'.format(3.14159) produces '3.14'. The .2 specifies two decimal places, and the f specifies fixed-point notation. You can also use e for scientific notation, % for percentage display, and d for integers. The colon always separates the field name from the format specifier.

Can I reuse the same value in multiple places within a format string?

Yes, by using positional indices. Writing '{0} comes before {0}'.format('Python') produces 'Python comes before Python'. Each curly brace pair with the same number refers to the same positional argument. You can also mix positional and keyword arguments, using numbers for positional and names like {name} for keyword.

Conclusion

The str.format() method gives you precise control over how values appear in string output. Positional and keyword placeholders let you reference arguments flexibly, and the format specification mini-language provides fine-grained control over decimal places, field widths, alignment, and padding. While f-strings are often preferred for inline formatting in modern Python, the format() method remains essential for template-driven formatting and situations where the format string and the data live separately.