Back to Blog
Python

Python Formatted String Literals: Syntax and Usage

python formatted string literal: Understand Python formatted string literals (f-strings): syntax, expressions, format specifiers, performance, and common pitfalls for...

f-stringsstring formattingPython syntaxPython 3code readability
Diagram showing an f-string with embedded variables and format specifiers in Python code.

Python formatted string literals, commonly called f-strings, are the most direct way to embed expressions inside string literals in Python. Introduced in Python 3.6, they use a leading f or F prefix and evaluate expressions inside curly braces at runtime.

name = "Ada" print(f"Hello, {name}")

This article explains the syntax, how expressions and format specifiers work, the performance characteristics of f-strings compared to older formatting methods, and the pitfalls that trip up developers when they move beyond simple variable interpolation.

What Makes an f-String Different

An f-string is a string literal prefixed with f or F. The parser treats the content inside {} as a Python expression, evaluates it, and converts the result to a string using str(). This happens at runtime, not at parse time, which means the expression can reference variables and call functions.

import math print(f"Pi is approximately {math.pi:.2f}")

The expression inside the braces can be any valid Python expression, including attribute access, method calls, and arithmetic. The result is formatted according to the optional format specifier that follows a colon.

Expressions Inside Braces

The expression is evaluated in the current scope. You can use variables, literals, and even complex expressions.

items = ["apple", "banana"] print(f"Count: {len(items)}") print(f"Total: {sum(item * 2 for item in [1, 2, 3])}")

Be careful with side effects: the expression is evaluated every time the f-string is executed. If you call a function that has side effects, it will run each time the string is created.

Format Specifiers and Alignment

Format specifiers control how the value is presented. They follow the same syntax as str.format().

value = 42.56789 print(f"Value: {value:.2f}") # 42.57 print(f"Percent: {value:.1%}") # 4256.8% print(f"Right aligned: {value:>10}") # " 42.56789"

You can also specify fill characters, width, and alignment for strings and numbers.

Nested f-Strings and Dynamic Formatting

Format specifiers can themselves be expressions. This allows you to build the format string dynamically.

width = 10 precision = 3 value = 3.14159 print(f"{value:{width}.{precision}f}") # " 3.142"

Nested braces are evaluated from the inside out. This is useful when the format specifier depends on runtime data, such as a column width read from a configuration file.

Debugging with the = Specifier

Python 3.8 added the = specifier to f-strings, which prints the expression and its value.

name = "Grace" print(f"{name=}") # name='Grace'

This is a convenient way to debug without writing separate print statements. The expression is evaluated and then the literal text of the expression is included in the output.

Performance and Runtime Cost

F-strings are generally faster than %-formatting and str.format() because they avoid the overhead of parsing a format string at runtime. The format string is parsed once at compile time, and the expressions are evaluated directly. For most applications, the difference is negligible, but in tight loops that format thousands of strings, f-strings can reduce CPU usage.

The main cost is the evaluation of the expressions themselves. If an expression is expensive, such as a database query, it will run every time the f-string is constructed. There is no lazy evaluation; the string is built immediately.

Common Pitfalls and How to Avoid Them

Quotes and backslashes inside expressions are a frequent source of errors. Because the f-string is a string literal, you cannot use the same quote character inside the expression unless you escape it or use a different quote style.

# This fails: SyntaxError # f"Result: {value["key"]}" # Use single quotes inside double-quoted f-string f"Result: {value['key']}"

Backslashes are not allowed inside the expression part of an f-string in Python versions before 3.12. In Python 3.12 and later, backslashes are permitted, but for compatibility, it's safer to avoid them.

Curly braces themselves need to be doubled if you want a literal brace in the output.

print(f"{{}}") # {}

When Not to Use an f-String

F-strings are evaluated immediately, so they are not suitable for deferred formatting, such as logging frameworks that may choose to discard messages based on log level. In those cases, use lazy %-style formatting or pass the arguments separately.

Similarly, if you need to store a template that will be filled in later with different values, an f-string is not appropriate because it evaluates at definition time. Use str.format() or a template string instead.

F-strings are also not a good fit for user-supplied format strings, because the expression is evaluated in the current scope and can access arbitrary variables. If you need to allow users to define format templates, use a safer mechanism like string.Template or str.format() with explicit field names.

Compatibility and Maintainability

F-strings require Python 3.6 or later. If you support older Python versions, you cannot use them. Even within Python 3, the = debug specifier requires 3.8, and backslash support in expressions requires 3.12. When writing code that must run across a range of Python versions, check the minimum version before using these features.

For maintainability, keep the expressions inside braces simple. Complex expressions make the string hard to read and test. If you need to compute something, do it in a variable first.

# Hard to read print(f"The total is {sum(item.price for item in cart if item.quantity > 0) * 1.07:.2f}") # Easier to maintain subtotal = sum(item.price for item in cart if item.quantity > 0) total = subtotal * 1.07 print(f"The total is {total:.2f}")

This separation also makes it easier to unit test the calculation independently of the string formatting.

python formatted string literal: Practical Usage and Code Ex | RYUSLOG DEV