Python F-Strings Explained

Learn how to use Python f-strings to embed expressions directly inside string literals for clean, fast, and readable string formatting.

5 min read

F-strings are the most readable and efficient way to embed values and expressions inside strings in Python. Introduced in Python 3.6, f-strings let you write a variable name or any Python expression directly inside curly braces within a string literal, and Python evaluates the expression at runtime and inserts its string representation into the surrounding text. The result is formatting code that looks like the output it produces, with the dynamic parts clearly marked and the static parts standing as plain text.

If you have worked with the older str.format() method covered in the previous article on format strings in Python, you already know the replacement field syntax and the format specification mini-language. F-strings use exactly the same curly-brace syntax and the same specifiers, but instead of passing values as separate arguments to a method call, you write the values directly where they belong in the string. This eliminates the cognitive disconnect between position numbers in a template and arguments at the end of a line, and it makes the code faster because Python can optimize the evaluation at compile time.

F-strings are the recommended default for string formatting in all new Python code, and for good reason: they are shorter to write, easier to read, less error-prone than matching numbered arguments to numbered braces, and measurably faster than calling format(). The older methods still have their place when the template and the data are defined in different locations, but for the formatting that happens line by line inside your functions, f-strings are the right choice. If you are new to Python strings overall, the article on Python strings provides the foundational context for this topic.

Embedding variables and expressions

An f-string is a regular string literal prefixed with the letter f or F before the opening quote. Inside the string, any text enclosed in curly braces is treated as a Python expression, evaluated, and converted to a string using the same rules as the str() built-in function. You can put a variable name, an arithmetic calculation, a function call, an attribute access, or nearly any other valid Python expression inside the braces.

pythonpython
name = "Maya"
tasks = 5
print(f"{name} has {tasks} tasks remaining")
# Maya has 5 tasks remaining
 
print(f"Double that is {tasks * 2} tasks")
# Double that is 10 tasks

The expression inside the braces is normal Python code and has access to all variables that are in scope at the point where the f-string appears. This includes local variables, function parameters, global variables, and imported module names. You can call methods on objects, index into lists and dictionaries, and use conditional expressions. The only notable restriction is that backslashes are not allowed inside the expression, which means you cannot use escape sequences or line continuations inside the braces. For dictionaries, you need to use a different quoting strategy for the dict key to avoid conflicting with the f-string's own quotes.

The format specification mini-language, identical to what str.format() uses, follows a colon after the expression. You can control decimal places, field width, alignment, zero-padding, and all the other formatting options without any change in syntax from what you learned in the previous article. The expression is evaluated first, and then the format specifier is applied to the resulting value, giving you full control over how each embedded piece appears in the final string.

The debug specifier with equals

One of the most practical features of f-strings for everyday development is the debug specifier, added in Python 3.8. When you place an equals sign immediately after the expression inside the braces, Python prints both the text of the expression and its evaluated value, separated by the equals sign. This turns a single f-string into a self-documenting debug print statement.

For example, f'{name=}' produces name=Maya and f'{2 + 3=}' produces 2 + 3=5. The whitespace you include around the expression and the equals sign is preserved in the output, so adding spaces around the equals sign adds those spaces to the result. This feature eliminates the tedious pattern of writing print('name =', name) repeatedly while debugging, and it works with any expression, not just simple variable names.

The debug specifier automatically uses the repr() representation rather than the str() representation for the value, which means strings appear with their quotes and special characters are shown with escape sequences. This is deliberate because repr() output is more useful for debugging: you can see the difference between the string "42" and the integer 42, and you can spot invisible characters like trailing spaces or newlines that would be hidden by the normal str() representation.

Rune AI

Rune AI

Key Insights

  • Prefix a string with f or F to create an f-string; embed expressions in curly braces: f'Hello, {name}'.
  • Use the same format specifiers as str.format(): f'{price:.2f}' for two decimal places.
  • Append = to an expression for debug output: f'{count=}' prints 'count=42'.
  • F-strings are evaluated at compile time, making them faster than str.format().
  • Any Python expression works inside braces, including arithmetic, function calls, and attribute access.
RunePowered by Rune AI

Frequently Asked Questions

What is an f-string in Python?

An f-string, formally called a formatted string literal, is a string prefixed with the letter f or F that allows embedding Python expressions directly inside curly braces within the string. When Python evaluates the f-string, it replaces each brace-delimited expression with its string value. F-strings were added in Python 3.6 and are the recommended way to format strings in modern Python because they are concise, readable, and faster than the older format() method.

Can I put any Python expression inside an f-string?

Almost any valid Python expression can go inside the curly braces of an f-string, including arithmetic, function calls, method calls, attribute access, and conditional expressions. You cannot use backslashes inside the expression, and you cannot use a colon or exclamation mark without proper formatting context. Starting in Python 3.12, nested f-strings and comments within expressions are also permitted, removing several earlier restrictions.

What does the equals sign do in an f-string?

Appending an equals sign after the expression name, like f'{name=}', prints both the expression text and its value. For example, f'{2+2=}' produces '2+2=4'. This debug specifier was added in Python 3.8 and is extremely useful for quick debugging and logging. Whitespace around the equals sign is preserved in the output, so f'{x = }' produces 'x = 42' with spaces.

Conclusion

F-strings are the modern, recommended way to format strings in Python. They are concise, readable, and faster than the older format() method because Python evaluates them at compile time rather than at runtime. The familiar curly-brace syntax, combined with the full format specification mini-language and the convenient equals-sign debug mode, covers nearly every formatting need with less code than any alternative.