Advertisement
Python keeps things simple, which is why so many developers stick with it instead of dealing with heavier languages. But for a long time, formatting strings was one of the clunkier parts of Python. Before version 3.6, you had to use .format() or the old % style—both worked, but they felt awkward and took extra effort to read and write. That changed when f-strings showed up. Suddenly, formatting became quicker and easier to read.
Add an f before the string, toss your variables or expressions into curly braces, and you're done. It reads like plain English. But f-strings go beyond just plugging in values—they let you format numbers, align text, run expressions, and clean up your output without breaking a sweat. If you write Python regularly, getting comfortable with f-strings is one of the simplest ways to make your code cleaner and easier to manage.
This is the most common use. If you’ve got a variable and want to plug it into a string, f-strings make it easy. You just write an f in front of the string and put the variable inside curly braces.
name = "Arjun"
print(f"Hello, {name}")
This replaces {name} with the value of the variable. It feels like regular text, which makes reading and writing code smoother. You can use any number of variables in one string.
age = 28
print(f"{name} is {age} years old.")
No need to worry about order or type—Python handles it under the hood.
You’re not limited to variables. You can put actual expressions inside the curly braces.
a = 5
b = 3
print(f"The sum is {a + b}")
You can even call functions or use method chains.
text = "hello"
print(f"{text.upper()} there")
This cuts down on extra lines just to compute something before printing. It keeps related logic inside the string, where it belongs.
When you want your numbers to look a certain way—maybe with two decimal places or as percentages—f-strings help.
value = 123.45678
print(f"{value:.2f}") # 123.46
The .2f tells Python to format the float to two decimal places. This works well when you’re printing currency or measurements.
For percentages:
score = 0.845
print(f"{score:.1%}") # 84.5%
You can even add commas for large numbers:
amount = 1000000
print(f"{amount:,}") # 1,000,000
Sometimes, you need things to line up. With f-strings, you can align text left, right, or center using <, >, or ^ inside the format specifier.
name = "Priya"
print(f"{name:<10} | left aligned")
print(f"{name:>10} | right aligned")
print(f"{name:^10} | centered")
This is handy in tables or any structured output.
There are times when you want to build strings inside strings. f-strings support that, too.
user = {"name": "Rahul", "score": 95}
print(f"{user['name']} scored {f'{user['score']:.1f}'} points")
While it works, this can get hard to read fast. If you find yourself doing too much nesting, it’s better to break it into parts for clarity.
This is a newer feature from Python 3.8. You can print both the variable and its value with a single syntax using =, which helps with debugging.
x = 42
print(f"{x=}") # x=42
If you include expressions, it shows both the expression and its result.
a = 10
b = 5
print(f"{a + b=}") # a + b=15
It saves you from writing separate strings just to check variable values during testing.
Python lets you use f-strings across multiple lines, especially when writing longer text blocks or formatted messages.
name = "Ayesha"
job = "engineer"
message = (
f"Name: {name}\n"
f"Occupation: {job}\n"
f"Status: Active"
)
print(message)
Each line remains readable, and you still get all the benefits of formatting. This avoids string concatenation or weird line breaks from older methods.
You can access dictionary values and object attributes directly inside f-strings.
person = {"first": "Neha", "last": "Singh"}
print(f"{person['first']} {person['last']}")
With objects:
class Car:
def __init__(self, brand, year):
self.brand = brand
self.year = year
c = Car("Toyota", 2020)
print(f"{c.brand} - {c.year}")
This avoids unpacking or assigning extra variables just to build a string.
When working with datetime objects, f-strings can format them directly using strftime patterns. You don't need to call .strftime() outside the string—you can do it inside the braces.
from datetime import datetime
now = datetime.now()
print(f"Today is {now:%Y-%m-%d}")
This prints something like:
Today is 2025-05-31
You can also format time:
print(f"The current time is {now:%H:%M:%S}")
It works cleanly and keeps formatting close to where you're using the data. It avoids extra lines and improves readability in logs or user messages that need formatted dates.
Sometimes, you want to control whether the string output should be in a readable form (str) or a more detailed version used for debugging (repr). With f-strings, you can do that using !s for str() and !r for repr() directly inside the curly braces.
value = 'hello\nworld'
print(f"{value!s}") # Prints the string as-is
print(f"{value!r}") # Prints the string with escape characters
This is helpful when you want to inspect values that might contain special characters, whitespace, or escape codes. It's especially useful during debugging, testing, or when you’re logging raw data.
f-strings changed the way Python handles string formatting. They make your code tighter and easier to follow. Once you start using them, going back to .format() or % feels like extra work. They’re flexible enough to handle variables, expressions, formatting rules, alignment, and more—all without slowing you down or making the code harder to read. Whether you're working on a script, building logs, or cleaning up old code, knowing how to use f-strings properly can make a real difference. The more you use them, the more you’ll notice how much cleaner your output becomes.
Advertisement
Google risks losing Samsung to Bing if it fails to enhance AI-powered mobile search and deliver smarter, better, faster results
Ready to make computers see like humans? Learn how to get started with OpenCV—install it, process images, apply filters, and build a real foundation in computer vision with just Python
How does Docmatix reshape document understanding for machines? See why this real-world dataset with diverse layouts, OCR, and multilingual data is now essential for building DocVQA systems
Achieve lightning-fast SetFit Inference on Intel Xeon processors with Hugging Face Optimum Intel. Discover how to reduce latency, optimize performance, and streamline deployment without compromising model accuracy
Can small AI agents understand what they see? Discover how adding vision transforms SmolAgents from scripted tools into adaptable systems that respond to real-world environments
Discover a clear SQL and PL/SQL comparison to understand how these two database languages differ and complement each other. Learn when to use each effectively
Can AI really help a Formula One team build faster, smarter cars? With real-time data crunching, simulation, and design automation, teams are transforming racing—long before the track lights go green
How benchmarking text generation inference helps evaluate speed, output quality, and model inference performance across real-world applications and workloads
What non-generalization and generalization mean in machine learning models, why they happen, and how to improve model generalization for reliable predictions
How Building Multi-Agent Framework with AutoGen enables efficient collaboration between AI agents, making complex tasks more manageable and modular
Accelerate AI with AWS GenAI tools offering scalable image creation and model training using Bedrock and SageMaker features
An AI health care company is transforming diagnostics by applying generative AI in radiology, achieving a $525M valuation while improving accuracy and supporting clinicians