An introduction to f-strings and string formatting

Henry George
Aug 21 · 6 min read

How do I add my variable into a string in Python? If I have someone’s name, how do I print this back out, with additional information, like a hello message?

Define string formatting:

Noun. The fancy way of saying: “Making strings/text look the way you want them to, whether that’s with variables, new lines, spaces, capital letters, etc.

Example: “The string formatting on the output of this simple command-line app is great, it has colors and everything!

String formatting has come a long way in the last few years. Let’s take a quick trip down memory lane and look at the old ways of formatting strings, scroll to the bottom to see some f-string examples.


Starting From Basics

In Python, everything is an object, this includes strings. This provides additional flexibility, e.g.: "a" * 4 == "aaaa", that is, you can 'concatenate' strings through addition and multiplication.

In the good ol’ days, this is how we used to do it. Let’s take a classic Python2 Hello World application, for example.

#!/usr/bin/env python 
name = input("What's your name? ")
print "Hello " + name

In this example, we use the most basic version of string formatting available. Concatenating (adding) two strings with the + symbol.

If you save this code into hello_name.py and run python3 hello_name.py, you'll see the output as Hello Henry, with Henry replaced by whatever you type in.

This is great for basic scripts, and makes sense when reading it but what if we want to do something like "Hello " + name + ", looks like the weather will be " + weather_temp + " " + weather_scale + " degrees today.".

This is still possible but definitely not very easy to read.

What if we want to take a number like 123.45678 and print it as $123.46? This method is clearly quite limited when it comes to string formatting.


The Magic of %

So, let’s go back to our example.

Say we have a float (a number with decimals, as in, not an integer) and we want to print it as a currency, with commas and rounding.

How do we do this?

amount = float(input("How much? ")) # Convert input (str) to float print("This much? " + amount)

If we input 1234.56789, we get back "This much? 1234.56789". So, how do we print this as a number of dollars and cents?

We can use something called the string formatting operator, or %. Instead of adding the string at the end, we can just place a % symbol, followed by a type (like d for integer, f for float, s for string, etc.) and then follow this with the variable to replace. This provides for (slightly) more readable code.

Our example above would then be:

amount = float(input("How much? ")) # Convert input (str) to float print("This much? %f" % amount)

But, this still doesn’t help us convert 1234.56789 to $1,234.57.

To do this, we need to use conversion flags.

For example, if we are formatting a float, we can replace %f with %.2f and this will round the float to two decimal places.

amount = float(input("How much? ")) # Convert input (str) to float print("This much? $%.2f" % amount)

So, now our output is $1234.57 but we still don't have the comma for the thousand separator...


You Can’t Spell ‘String Formatting’ Without Format

So, everything in Python is an object. Objects can have methods (functions) so why don’t we just add a method to the string object to help us format strings?

Welcome string.format().

This was a big leap forward for Python. We didn’t just gain a more readable way of formatting strings (more on this in footnotes), we also gained more complex formatting rules.

Let’s go back to our example.

Say we have a float (a number with decimals, as in, not an integer) and we want to print it as a currency, with commas and rounding. How do we do this?

amount = float(input("How much? ")) # Convert input (str) to float print("This much? ${0:,.2f}".format(amount))

Our output is now This much? $1,234.57 but how?

The basic syntax of format is that it takes the first argument (value after the brackets, so .format(first, second) has two arguments, first and second), and places this in the first index (denoted by 0), so x = 123, "The number is {0}".format(x) returns The number is 123.

The , tells Python to format the number with commas, so 1200000 becomes 1,200,000 (if you're building an international application, remember that in some countries the , and . symbol are reversed).

Okay, so .format can do everything we want. Then why do you like f-strings so much?


The Real Reason F-Strings Will Change Your Life

Despite common perceptions, development isn’t (and shouldn’t be) about getting the job done. It’s about getting the job done well and in a way that future developers will be able to understand and extend.

String.format has all the functionality you need. Python 2.7 has all the functionality you need. In fact, C has all the functionality you need, to do almost any task.

When python upgraded to version 3, it made some radical, breaking changes to the language, and while some were for performance and some were for functionality, my personal favorite, f-strings, was primarily for robustness, readability, and adaptability.

F-strings don’t introduce any new functionality but they drastically increase readability and adaptability (they also increase performance, but this, to me, is a side note).

Let’s take a simple example first:

name = "Jenny" 
company = "Acme Inc."
print(f"Hi {name}, welcome to {company}.")

>>> 'Hi Jenny, welcome to Acme Inc'

By simply adding an f before the string, we’ve been able to input any variable we have in the current scope, and print it in a string. This isn’t really revolutionary but what is revolutionary is how easy it is to understand.

In today’s world, code isn’t written once to perform a function, it’s written, tested, reviewed, modified, extended, and, one day, maybe replaced.

Readability is key to this and f-strings have provided a massive jump in readability. If you knew nothing about Python at all and you looked at the previous example, I would bet you could guess what the output looked like.

Never underestimate how valuable readability is. With our simple examples, it seems almost too easy but let’s look at a more complex example, making an SQL query.

col1 = 'bar' 
col2 = 'baz'
query = f'SELECT * FROM foo WHERE {col1} = ? AND {col2} = ?' cursor.execute(query, params)

This query returns all rows where the values in the columns bar and baz are equal to the values set in params. This isn’t as exciting but much more valuable, and more likely in an enterprise setting.

If we rewrite this with a % operator, or a .format() function, it quickly becomes more difficult to read.

The formatting available to f-strings is similar to .format, so I won’t include it in this document but I hope I’ve convinced you that f-strings are valuable. For testing, readability, extensibility, and more.


Fun Facts

  • You can use either a lowercase, or a capital F, and the string formatting will be the same. f"The result is {result}" is the same as F"The result is {result}".
  • If you want to format strings over multiple lines, you can put an f in front of each line with a variable:
print( 
f"Hi {name}"
"welcome to my post"
f"you're {num_days} late"
)
  • Or, you can simply use Python’s multi-line strings (denoted by triple quotes, or tripe double quotes):
print( 
f"""Hi {name}
welcome to my post
you're {num_days} late"""
)

Clever Facts

decimals = 3 
amount = float(input("How much? ")) # Convert input (str) to float print(f"This much? ${amount:,.{decimals}f}")

With input of 12312.123123, the output of this script is This much? $12,312.123.

Note: Please don’t do this, this is really difficult to read.

E.g.:

data = {"x": 123} 
print(f'The result is {data["x"]}')

Or, equivalently:

data = {"x": 123} 
print(f"The result is {data['x']}")

Better Programming

Advice for programmers.

Henry George

Written by

Entrepreneur, Developer, Mathematician. Artificial Intelligence, Startups and Software Development.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade