f-string
Python f-string is the newest Python syntax to do string formatting. 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.
Python string formatting
The following example summarizes string formatting options in Python:
name = 'Peter'
age = 23
print('%s is %d years old' % (name, age)) # C style
print('{} is {} years old'.format(name, age)) # python format function
print(f'{name} is {age} years old') # f-string
Peter is 23 years old
Peter is 23 years old
Peter is 23 years old
f-string usage
f-string expressions
We can put expressions between the {}
brackets, and the expression will be evaluated inside f-string
bags = 3
apples_in_bag = 12
print(f'There are total of {bags * apples_in_bag} apples')
There are total of 36 apples
f-string dictionaries
user = {'name': 'John Doe', 'occupation': 'gardener'}
print(f"{user['name']} is a {user['occupation']}")
John Doe is a gardener
f-string debug
Python 3.8 introduced the self-documenting expression with the =
character.
import math
x = 0.8
print(f'{math.cos(x) = }')
print(f'{math.sin(x) = }')
math.cos(x) = 0.6967067093471654
math.sin(x) = 0.7173560908995228
multiline f-string
- The f-strings are placed between round brackets
- Each of the strings is preceded with the
f
character
name = 'John Doe'
age = 32
occupation = 'gardener'
msg = (
f'Name: {name}\n'
f'Age: {age}\n'
f'Occupation: {occupation}'
)
print(msg)
Name: John Doe
Age: 32
Occupation: gardener
f-string calling function
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)}')
Max of 3 and 4 is 4
f-string objects
Python f-string accepts objects as well; the objects must have either __str__()
or __repr__()
magic functions defined.
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}')
John Doe is a gardener
f-string format
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.
val = 12.3
print(f'{val:.2f}')
print(f'{val:.5f}')
12.30
12.30000
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.
for x in range(1, 11):
print(f'{x:02} {x*x:3} {x*x*x:4}')
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
We can combine floats precision and width, for example:
import numpy as np
a = np.random.rand(20)
for index, value in enumerate(a):
if index < 10:
print(f'{index:2}: {value:4.4f}')
else:
print(f'{index:2}: {value:4.3f}')
0: 0.1398
1: 0.7079
2: 0.2034
3: 0.5995
4: 0.7553
5: 0.6342
6: 0.4282
7: 0.4405
8: 0.1145
9: 0.3309
10: 0.127
11: 0.156
12: 0.309
13: 0.845
14: 0.816
15: 0.694
16: 0.291
17: 0.440
18: 0.469
19: 0.305
{value:4.4f}
means
- We will use a width of 4-character to print
value
- The precision of
value
is 4: we will keep 4 decimal places
!r
, !s
, and !a
The conversions !r
, !s
, and !a
are equivalent to calling repr()
, str()
, and ascii()
, respectively.
Example:
>> a = 'some string'
>>> f'{a!r}'
"'some string'"
is identical to
>>> f'{repr(a)}'
"'some string'"
The usage of these conversion are not strictly required, because explicitly calling the corresponding functions is arguably more clear in its intent. In other words, they are redundant.
!r
(repr
), !s
(str
) and !a
(ascii
) are kept around just to ease compatibility with the str.format()
alternative, because it does not allow the execution of arbitrary expressions. You don’t need to use them with f-strings.
Reference: