LambdaLabTM
Computer Science · Class 11 · More about print()
print()f-strings⏱️ 13 min read

What an f-string Is

Putting a value inside a sentence has cost you something on every page so far — either commas that force a space you may not want, or + with str() wrapped round every number. An f-string is the third way: write the sentence, and put the value in it, in braces.

1The same line, three ways

three_ways.py
# the same line, three ways

name = 'Asha'
marks = 91

print('Name:', name, 'Marks:', marks)
print('Name: ' + name + ' Marks: ' + str(marks))
print(f'Name: {name} Marks: {marks}')
Output
Name: Asha Marks: 91
Name: Asha Marks: 91
Name: Asha Marks: 91
waywhat it costs you
commasA space appears between every argument whether you want one or not. Nothing to convert, nothing to break.
+ and str()Total control of the spacing, and a str() round every number — miss one and it is a TypeError.
f-stringTotal control of the spacing, no str() anywhere, and the sentence reads as the sentence it will print.

2The two parts: the f, and the braces

anatomy.py
print(f'Name: {name} Marks: {marks}')
        |       |    |
        |       |    +-- a PLACEHOLDER: the braces and what is in them,
        |       |        replaced by the value when the string is used
        |       +------- ordinary text, printed exactly as written
        +--------------- the f, immediately before the quote
Key Takeaway
The braces are called placeholders. They hold the place where a value will go — which is exactly what the word means, and it is the name your textbook and your paper will use. Python's own documentation calls the same thing a replacement field, because the whole {...} is replaced by whatever it holds. Two names, one thing; recognise both and use whichever the question uses.
Key Takeaway
Without the f, the braces are just characters. Python does not look inside '{name}' at all — it prints the braces and the word. The f is what turns an ordinary string into one that gets read for braces before it is used, and it goes immediately before the opening quote, with no space.
mistakes.py
# the f is not optional, and neither are the braces

name = 'Asha'

print(f'Hello {name}')
print('Hello {name}')
print(f'Hello name')
Output
Hello Asha
Hello {name}
Hello name

Three lines, three different mistakes to recognise. The second forgot the f, so nothing was replaced and the braces printed themselves. The third had the f but no braces, so name was just a word in a sentence. Neither is an error — both print something, and that is what makes them worth meeting on purpose.

3Anything that has a value can go in the braces

Not only names. Whatever is between the braces is worked out first, exactly as if it had been written on its own line, and the answer is dropped into the sentence:

inside_braces.py
# what goes inside the braces is worked out first

a = 7
b = 3

print(f'{a} + {b} = {a + b}')
print(f'{a} // {b} = {a // b}')
print(f'{a} is bigger than {b}: {a > b}')

word = 'python'
print(f'{word} has {len(word)} letters and starts with {word[0]}')
Output
7 + 3 = 10
7 // 3 = 2
7 is bigger than 3: True
python has 6 letters and starts with p
f'{a} + {b} = {a + b}'

Three braces. The first two hold names; the third holds a whole expression, worked out on the spot. The + between the first two braces is ordinary text — it is outside the braces, so nothing is added.

f'... {a > b}'

A comparison has a value too, so it can go in a brace. It prints True or False with a capital letter, because that is how Python writes them.

f'{word} has {len(word)} letters'

A function call inside a brace. Anything you could put on the right of an = can go in there, which is most of the language.

Watch Out
A name in braces still has to exist. f'Hello {student}' with no student anywhere raises NameError: name 'student' is not defined, exactly as it would outside a string. The braces do not create anything — they look up.

4Where you will use it most: prompts and answers

An f-string works anywhere a string works, not only inside print() — including as the prompt of an input(), which is where all that 'Enter number ' + str(i + 1) joining came from:

prompt.py
# the reading loop, with the prompt written as a sentence

n = int(input('How many numbers? '))
numbers = []

for i in range(n):
    numbers.append(int(input(f'Enter number {i + 1}: ')))

print(f'You entered {len(numbers)} numbers: {numbers}')
Output
How many numbers? 3
Enter number 1: 10
Enter number 2: 20
Enter number 3: 30
You entered 3 numbers: [10, 20, 30]

Compare that middle line with the version from the lists chapter — 'Enter number ' + str(i + 1) + ': ' — and the argument for f-strings makes itself. Same output, one str() fewer, and the prompt is readable as a prompt.

fstring_play.py

5One rule about quotes

An f-string is still a string, so the quote that ends it is still the quote that started it. If the braces need quotes of their own — for a dictionary key, say — use the other kind:

quotes.py
# the inner quotes must differ from the outer ones

marks = {'Asha': 91, 'Ravi': 65}

print(f"Asha scored {marks['Asha']}")
print(f'Ravi scored {marks["Ravi"]}')
Output
Asha scored 91
Ravi scored 65
Tip
This is the same rule as any string. Double quotes outside, single inside — or the other way round. It is worth knowing because a dictionary lookup inside an f-string is the first place most people meet it.

6Recap

f, then the quote, then braces

The f goes immediately before the opening quote. Without it the braces are ordinary characters and print themselves.

The braces are placeholders

Python's own name for one is a replacement field. Whichever word is used, the whole {…} is replaced by the value it holds.

A placeholder is worked out first

A name, a sum, a comparison, a function call — anything that has a value. The answer is dropped in where the braces were.

No str() anywhere

Numbers, True and False and lists all go in as they are. That is the whole reason it beats joining with +.

It is a string like any other

Usable as an input() prompt, stored in a variable, joined with +. And the inner quotes must differ from the outer ones.

a reminder of what the three mistakes look like
Output
Hello Asha        <- f'Hello {name}'   — correct
Hello {name}      <- 'Hello {name}'    — the f was forgotten
Hello name        <- f'Hello name'     — the braces were forgotten
Quick Check

name = 'Asha'. What does print('Hello {name}') show?

Quick Check

What does f'{7} + {3} = {7 + 3}' produce?

Quick Check

Why does f'Enter number {i + 1}: ' need no str()?