A Guide to String Formatting in Python

A guide to the various methods used to format strings in Python, including f-strings, with worked examples.
Andrew Wood  •   03 June 2022
Andrew Wood  •   Last Updated: 03 June 2022
A guide to the various methods used to format strings in Python, including f-strings, with worked examples.

This guide has been written to summarise the various methods used to format strings in Python. Python's string formatting methods have evolved as the language has developed and there are now three ways to format strings natively without importing any additional modules.

A Little History

The original string formatting method, the printf style, follows a similar approach to the printf formatting you find in the C language. It has now largely been replaced with newer, more powerful methods, but has not been deprecated and is still available in all Python versions. That being said, the official Python documentation suggests that you would be better off working with the newer formatting methods if/when available.

When Python 3 was released it shipped with a new str.format() function which was later ported back to Python 2.7. This string formatting method uses normal Python function call syntax and is therefore preferred to the fprint method.  

Finally, a new method to format strings, formatted string literals or the so-called f-string method was introduced in Python 3.6. This new method offers some important additional functionality – principally the ability to embed python expressions into the string constants. This gives you a much broader scope as to how you format strings; for example, you can now perform mathematical operations on-the-fly within the string as you format it. It is also viewed as more readable and concise than previous methods and should be the preferred choice if given the option of all three.

The best way to examine these three formats is to work through each of them with a set of examples. Let’s get started.

Printf Style Formatting

The printf string formatting style is characterised by the use of the modulo operator %, inserted into a string to indicate where in that string to place a variable. The ‘s’ in the example below is called a conversion specifier, and tells python to apply the str() function to the variable, and turn that variable into a string for printing.

>>> name = 'Pat'
>>> print("Hello, %s" %(name))
"Hello, Pat"

There are a number of different conversion specifiers at your disposal. For a full list refer to the official documentation. Those which you are most likely to use are shown in the table below.

Conversion Meaning
's' String (makes use of the str() function).
'e' Floating point exponential format (lowercase)
'f' Floating point decimal format.
'd' Signed integer decimal
'x' Signed hexadecimal (lowercase)

In practice it is more common to place multiple variables within the string rather than just one. If that is the case, then the order in which you list the variables to the right of the string becomes very important. The order in which the variables are listed must match the order in which they are used in the string or else you will end up with some strange results!

>>> name = "Joe"
>>> age = 28
>>> occupation = "astronaut"

>>> greeting = "My name is %s and I am a %s year old %s." % (name,age,occupation)
>>> print(greeting)
"My name is Joe and I am a 28 year old astronaut."

>>> greeting = "My name is %s and I am a %s year old %s." % (age,occupation,name)
>>> print(greeting)
"My name is 28 and I am a astronaut year old Joe."

A more explicit way of working with printf style formatting is to house the variables in a standard Python dictionary and then refer to the dictionary key in the string as shown in the next example. This is my preferred method of working if I am using printf formatting as I prefer to be as explicit as possible.

>>> greeting_dict = {
       'name':name,
       'age':age,
       'occupation':occupation,
  }

>>> explicitgreeting = "My name is %(name)s and 
                       I am a %(age)s year old %(occupation)s." % greeting_dict
>>> print(explicitgreeting)
"My name is Joe and I am a 28 year old astronaut."

Our final printf example highlights the role that the conversion specifier plays in the string output. Here we print out the value of pi using some of the common specifiers.

We can control the number of digits to display when using floating point numbers (%f) with the syntax %a.bf where ‘a’ states the minimum number of digits to display (will add whitespace to make up the required number of digits if necessary) and ‘b’ refers to the number of decimal places to use.

>>> import math
>>> pi = math.pi

>>> print("The value of pi is: %s." %pi) # runs str(pi)
"The value of pi is: 3.141592653589793."

>>> print("The value of pi is: %e." %pi) # lowercase floating point exponential
"The value of pi is: 3.141593e+00."

>>> print("The value of pi is: %6.5f." %pi) # floating point decimal format
"The value of pi is: 3.14159."

>>> print("The value of pi is: %d." %pi) # integer
"The value of pi is: 3."

String Formatting using the str.format Method

This method was introduced when Python 3 was released and then back-ported to Python 2.7. It offers a more pythonic way to approach string formatting as it uses the normal Python function call syntax. Positional formatting is accomplished by calling the .format() method after the string. Curly braces {} denote where in the string to add the variable.

>>> print("Hello {}, nice to {} you!".format('bob','meet'))
"Hello bob, nice to meet you!"

As soon as you have more than one variable to insert, it is best to name the variables as shown in the example below. By naming the variables you can then place them in any order in the format method.

>>> name = "Sam"
>>> age = 54
>>> occupation = "artist"

>>> greeting = "My name is {name} and I am a {age} year old 
               {occupation}.".format(age=age,occupation=occupation,name=name)
>>> print(greeting)
"My name is Sam and I am a 54 year old artist."

Perhaps the nicest implementation of a multi-variable string is through the use of a dictionary where you can unpack the dictionary automatically using .format(**my_dict_name).

>>> my_dict = {'name':"Chris",'age':34,'occupation':"rocketman"}

>>> greeting = "My name is {name} and I am a {age} year old {occupation}.".format(**my_dict)
>>> print(greeting)
"My name is Chris and I am a 34 year old rocketman."

Conversion specifiers are also used in the .format() method as illustrated below.

>>> import math
>>> pi = math.pi

>>> print("The value of pi is: {pi}.".format(pi=pi)) # runs str(pi)
"The value of pi is: 3.141592653589793."

>>> print("The value of pi is: {pi:e}.".format(pi=pi)) # lowercase exponential
"The value of pi is: 3.141593e+00."

Formatted F-string Notation

This is the latest string formatting implementation and was added in Python 3.6. This notation is more readable, concise and faster than previous string formatting methods. If you are working in Python 3.6+ then it is the recommended string format method to use. The method is also known as Literal String Interpolation, but most refer to it as f-string notation due to the letter f which is placed ahead of the string when applying this method.

To initiate an f-string simply prefix the string with the letter f. The string is formatted in a similar way to the .format() method with the use of curly braces to denote where the variables are to be placed.

One big advantage of using f-strings is the ability to add embedded functions inside the string constants. Take a look at the next example where we have calculated the number of years worked by subtracting two variables from one-another; all inside the string.

>>> name = "Tina"
>>> age = 54
>>> started_work = 19
>>> occupation = "electrician"

>>> greeting = f'My name is {name} and 
                I am a {age} year old {occupation}. 
                I started working {age-started_work} years ago.'
>>> print(greeting)
"My name is Tina and I am a 54 year old electrician. I started working 35 years ago."

I personally like to use a dictionary to house my variables before applying them to the string. If you are going to use a dictionary then you need to use one set of quotation marks ("" or '') to start and end the string literal and another in the dictionary key calls or else you will trigger an error.

>>> greeting_dict = {
    'name':'Tina',
    'age':54,
    'occupation':'electrician',
    'started_work':19,
    }

>>> greeting = f"My name is {greeting_dict['name']} and 
                 I am a {greeting_dict['age']} year 
                 old {greeting_dict['occupation']}. 
                 I started working 
                 {greeting_dict['age']-greeting_dict['started_work']} 
                 years ago."

>>> print(greeting)
"My name is Tina and I am a 54 year old electrician. I started working 35 years ago."

Which Notation Should I use?

We have described three separate string notations that can be used to format strings so naturally the question will be – which should I use?

  • The f-string notation is the most recently added and has some advantages over the other methods; principally the ability to add expressions inside the string literal. If you are working with Python 3.6+ then this is the recommended method to use. 
  • If you are working with a version of Python older than 2.7 then you will have to use the printf notation as none of the others are available. 
  • The .format() method is still a popular choice and should always be used ahead of the printf method if f-strings are not available.
Share this
Comments
Canard Analytics Founder. Python development, data nerd, aerospace engineering and general aviation.
Profile picture of andreww
Share Article

Looking for a partner on your next project?

Contact Us