Python f-strings, written with an f before the opening quote, let you embed variable values directly inside a string using curly braces. They make output code far more readable than joining strings with + or calling format(). Introduced in Python 3.6, f-strings are now the standard approach at KS3 and GCSE level.
What is the basic syntax of an f-string?
An f-string begins with the letter f (or F) immediately before an opening quotation mark. Inside the string, anything placed in {} curly braces is evaluated as a Python expression and inserted into the string:
name = "Alice"
age = 14
print(f"My name is {name} and I am {age} years old.")
# Output: My name is Alice and I am 14 years old.
Compare this with the older string concatenation approach:
# Without f-strings — harder to read
print("My name is " + name + " and I am " + str(age) + " years old.")
The f-string version is much clearer. Notice that str(age) was required with concatenation (because you cannot join a string and an integer with +), but f-strings handle the type conversion automatically.
Can you put expressions inside f-string curly braces?
Yes — curly braces in an f-string can contain any valid Python expression, not just variable names:
a = 7
b = 3
print(f"The sum of {a} and {b} is {a + b}.")
# Output: The sum of 7 and 3 is 10.
print(f"Double {a} is {a * 2}.")
# Output: Double 7 is 14.
print(f"Is {a} greater than {b}? {a > b}")
# Output: Is 7 greater than 3? True
You can even call functions inside the braces:
word = "computing"
print(f"The word '{word}' has {len(word)} letters and starts with '{word[0].upper()}'.")
# Output: The word 'computing' has 9 letters and starts with 'C'.
How do you format numbers with f-strings?
F-strings support format specifiers — instructions placed after a colon inside the braces that control how a value is displayed.
Decimal places
Use :.Nf to display a float rounded to N decimal places:
price = 4.9999
print(f"Price: £{price:.2f}") # Output: Price: £5.00
pi = 3.14159265
print(f"Pi to 3 d.p.: {pi:.3f}") # Output: Pi to 3 d.p.: 3.142
Integer formatting
Use :d or just the variable for integers. Use , to add thousands separators:
population = 67000000
print(f"UK population: {population:,}")
# Output: UK population: 67,000,000
Width and alignment
# Right-align a number in a field 8 characters wide
score = 97
print(f"Score: {score:>8}") # Output: Score: 97
# Left-align text
name = "Bob"
print(f"|{name:<10}|") # Output: |Bob |
| Format specifier | Meaning | Example output |
|---|---|---|
:.2f |
Float to 2 decimal places | 3.14 |
:.0f |
Float rounded to integer | 3 |
:, |
Integer with comma separator | 1,000,000 |
:>8 |
Right-align in 8-char field | 42 |
:<8 |
Left-align in 8-char field | 42 |
:^8 |
Centre in 8-char field | 42 |
How does the older format() method compare?
Before f-strings (Python < 3.6), str.format() was the standard approach:
name = "Alice"
age = 14
print("My name is {} and I am {} years old.".format(name, age))
# Output: My name is Alice and I am 14 years old.
You could also name the placeholders:
print("Hello, {first}! You are in Year {year}.".format(first=name, year=9))
F-strings do everything format() can do, with less typing and better readability. At KS3 and GCSE, prefer f-strings in any code you write from 2024 onwards.
What about the old % formatting?
Even older Python code uses % formatting:
name = "Bob"
score = 85.5
print("Name: %s, Score: %.1f" % (name, score))
# Output: Name: Bob, Score: 85.5
This style was borrowed from the C programming language. You may encounter it in older textbooks or code, but it is now considered outdated. Do not use it in new code.
Frequently asked questions
Can an f-string span multiple lines?
Yes. Use triple quotes to create a multi-line f-string:
name = "Alice"
grade = "A"
print(f"""
Student report
--------------
Name: {name}
Grade: {grade}
""")
The output preserves the newlines inside the triple quotes. This is useful for generating formatted reports or structured output.
What happens if I put a string inside the curly braces?
You can include a string literal inside the curly braces of an f-string, but you must use different quote characters to avoid ending the f-string early:
# f-string uses double quotes — use single quotes inside braces
result = f"{'pass' if 80 > 50 else 'fail'}"
print(result) # Output: pass
In Python 3.12 and later, f-string restrictions around quote characters were relaxed, but at KS3 level it is safest to keep expressions inside braces simple and free of the same quote type as the outer string.
Do f-strings work with lists and dictionaries?
Yes. You can embed list indexing or dictionary lookups directly:
scores = [88, 72, 95]
info = {"name": "Carol", "year": 10}
print(f"Top score: {scores[2]}") # Output: Top score: 95
print(f"Student: {info['name']}, Year {info['year']}")
# Output: Student: Carol, Year 10
Is it better to use f-strings or concatenation in a loop?
F-strings are almost always better in a loop. Concatenation with + creates a new string object with each operation, which is inefficient for large loops. F-strings evaluate the expression once and build the output string directly, making them faster and more readable.
Practise string formatting challenges and get instant Professor Turing feedback at aitutors.me.