ZetCode

Python f-string

last modified March 13, 2024

Python f-string tutorial shows how to format strings in Python with f-string.

Python f-string is the newest Python syntax to do string formatting. It is available since Python 3.6. Python f-strings provide a faster, more readable, more concise, and less error prone way of formatting strings in Python.

The f-strings have the f prefix and use {} brackets to evaluate values.

Format specifiers for types, padding, or aligning are specified after the colon character; for instance: f'{price:.3}', where price is a variable name.

Python string formatting

The following example summarizes string formatting options in Python.

main.py
#!/usr/bin/python

name = 'Peter'
age = 23

print('%s is %d years old' % (name, age))
print('{} is {} years old'.format(name, age))
print(f'{name} is {age} years old')

The example formats a string using two variables.

print('%s is %d years old' % (name, age))

This is the oldest option. It uses the % operator and classic string format specifies such as %s and %d.

print('{} is {} years old'.format(name, age))

Since Python 3.0, the format function was introduced to provide advance formatting options.

print(f'{name} is {age} years old')

Python f-strings are available since Python 3.6. The string has the f prefix and uses {} to evaluate variables.

$ python main.py
Peter is 23 years old
Peter is 23 years old
Peter is 23 years old

Expressions

We can put expressions between the {} brackets.

main.py
#!/usr/bin/python

bags = 3
apples_in_bag = 12

print(f'There are total of {bags * apples_in_bag} apples')

The example evaluates an expression inside f-string.

$ python main.py
There are total of 36 apples

Using dictionaries

We can work with dictionaries in f-strings.

main.py
#!/usr/bin/python

user = {'name': 'John Doe', 'occupation': 'gardener'}

print(f"{user['name']} is a {user['occupation']}")

The example evaluates a dictionary in an f-string.

$ python main.py
John Doe is a gardener

The f-string debug option

Python 3.8 introduced the self-documenting expression with the = character.

main.py
#!/usr/bin/python

import math

x = 0.8

print(f'{math.cos(x) = }')
print(f'{math.sin(x) = }')

The example outputs the Sine and Cosine functions in the debug mode.

$ python main.py
math.cos(x) = 0.6967067093471654
math.sin(x) = 0.7173560908995228

Multiline f-strings

We can work with multiline strings.

main.py
#!/usr/bin/python

name = 'John Doe'
occupation = 'gardener'
age = 34

msg = f'''name: {name}
age: {age}
occupation: {occupation}'''

print(msg)

The example presents a multiline f-string.

$ python main.py
name: John Doe
age: 34
occupation: gardener

Calling functions

We can also call functions in f-strings.

main.py
#!/usr/bin/python

def mymax(x, y):

    return x if x > y else y

a = 3
b = 4

print(f'Max of {a} and {b} is {mymax(a, b)}')

The example calls a custom function in the f-string.

$ python main.py
Max of 3 and 4 is 4

The f-string objects

Python f-string accepts objects as well; the objects must have either __str__ or __repr__ magic functions defined.

main.py
#!/usr/bin/python

class User:
    def __init__(self, name, occupation):
        self.name = name
        self.occupation = occupation

    def __repr__(self):
        return f"{self.name} is a {self.occupation}"

u = User('John Doe', 'gardener')

print(f'{u}')

The example evaluates an object in the f-string.

$ python main.py
John Doe is a gardener

The __format__ method

The __format__ method gives us more control over how an object is formatted within an f-string. It allows us to define custom formatting behavior based on the format specifier provided within the f-string.

main.py
#!/usr/bin/python

from dataclasses import dataclass

@dataclass
class User:
    name: str
    occupation: str

    def __format__(self, spec):
        return f'User(name={self.name}{spec} occupation={self.occupation})'


u1 = User('John Doe', 'gardener')
u2 = User('Roger Roe', 'driver')
u3 = User('Lucia Smith', 'teacher')

print(f'{u1:-}')
print(f'{u2:;}')
print(f'{u3:#}')

We define a data object with a custom __format__ method.

def __format__(self, spec):
    return f'{self.name} {spec} {self.occupation}'

The method places the provided specifier between the fields of the object.

$ python main.py
User(name=John Doe- occupation=gardener)
User(name=Roger Roe; occupation=driver)
User(name=Lucia Smith# occupation=teacher)

Escaping characters

The following example shows how to escape certain characters in f-strings.

main.py
#!/usr/bin/python

print(f'Python uses {{}} to evaluate variables in f-strings')
print(f'This was a \'great\' film')

To escape a curly bracket, we double the character. A single quote is escaped with a backslash character.

$ python main.py
Python uses {} to evaluate variables in f-strings
This was a 'great' film

Python f-string format datetime

The following example formats datetime.

main.py
#!/usr/bin/python

import datetime

now = datetime.datetime.now()

print(f'{now:%Y-%m-%d %H:%M}')
print(f'{now:%A}')
print(f'{now:%a}')
print(f'{now:%B}')
print(f'{now:%j}')
print(f'{now:%w}')

The example displays a formatted current datetime. The datetime format specifiers follow the : character.

$ python main.py
2024-03-13 11:38
Wednesday
Wed
March
073
3

Nested expressions

It is possible to nest expressions within expressions.

main.py
#!/usr/bin/python

from datetime import datetime

today = datetime.now().date()

spec1 = '%d.%m.%y'
spec2 = '%y/%m/%d'

print(f'{today:{spec1}}')
print(f'{today:{spec2}}')

In the example, we use different format specifications. They are provided as spec variables and are evaluated as nested expressions.

$ python main.py
16.03.24
24/03/16

Formatting floats

Floating point values have the f suffix. We can also specify the precision: the number of decimal places. The precision is a value that goes right after the dot character.

main.py
#!/usr/bin/python

val = 12.3

print(f'{val:.2f}')
print(f'{val:.5f}')

The example prints a formatted floating point value.

$ python main.py
12.30
12.30000

The output shows the number having two and five decimal places.

Thousands separators

We can format numbers with underscore and command thousands separators.

main.py
#!/usr/bin/python

val = 1_200_400_001

print(val)
print(f'{val:_}')
print(f'{val:,}')

A big integer is printed in formats where thousand groups are separated with _ and ,.

$ python main.py
1200400001
1_200_400_001
1,200,400,001

Percentage

We display a decimal value as percentage using the % format specifier.

main.py
#!/usr/bin/python

val = 1/7.0

print(f'{val}')
print(f'{val:.2%}')

In the program, we display the 1/7 value as a percentage with two decimal places.

$ python main.py 
0.14285714285714285
14.29%

Format width

The width specifier sets the width of the value. The value may be filled with spaces or other characters if the value is shorter than the specified width.

main.py
#!/usr/bin/python

for x in range(1, 11):
    print(f'{x:02} {x*x:3} {x*x*x:4}')

The example prints three columns. Each of the columns has a predefined width. The first column uses 0 to fill shorter values.

$ python main.py
01   1    1
02   4    8
03   9   27
04  16   64
05  25  125
06  36  216
07  49  343
08  64  512
09  81  729
10 100 1000

Justifying strings

By default, the strings are justified to the left. We can use the > character to justify the strings to the right. The > character follows the colon character.

The ^ character centers the string.

main.py
#!/usr/bin/python

words = ['sky', 'fork', 'small', 'cup', 'car', 'war']

for word in words:
    print(f'|{word:>20}|')

for word in words:
    print(f'|{word:^20}|')

for word in words:
    print(f'|{word:<20}|')

We have a list of words. The words are aligned to the right, center, and left. Each of the outputs has twenty characters.

$ python main.py
|                 sky|
|                fork|
|               small|
|                 cup|
|                 car|
|                 war|
|        sky         |
|        fork        |
|       small        |
|        cup         |
|        car         |
|        war         |
|sky                 |
|fork                |
|small               |
|cup                 |
|car                 |
|war                 |

Numeric notations

Numbers can have various numeric notations, such as decadic or hexadecimal.

main.py
#!/usr/bin/python

val = 300

# hexadecimal lower
print(f'{val:x}')

# hexadecimal upper
print(f'{val:X}')

# octal
print(f'{val:o}')

# binary
print(f'{val:b}')

# scientific
print(f'{val:e}')

The example prints a value in various notations.

$ python main.py
12c
12C
454
100101100
3.000000e+02

Source

Python f-string - language reference

In this article we have worked with Python f-strings.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Python tutorials.