5 minutes read

Sometimes, you might need to insert variable values into text. Python has a helpful feature known as string formatting to assist with this. Let's look at what it is and how it helps.

Imagine you need to print a welcome message:

Hi, my name is , I am  years old!

Your immediate thought might be to use string concatenation like this:

name = 'John'
age = 20
print('Hi, my name is ' + name + ', I am ' + str(age) + ' years old!')  # an awkward way, considered a bad practice!
# prints 'Hi, my name is John, I am 20 years old!'

This strategy works, but it's not perfect. To address such tasks, Python offers you three methods of string formatting.

The % operator

This built-in operator comes from C-language. Let's use it for our welcome message:

name = 'John'
age = 20
print('Hi, my name is %s, I am %i years old!' % (name, age))  # an old-fashioned way of formatting
# prints 'Hi, my name is John, I am 20 years old!'

You see how we created placeholders for the string name (%s) and for the integer age (%i) then substituted the variables into the string using the % operator.

With the % character, we can also control the number of decimal places, for example, reduce their number to 3 or 2:

print('%.3f' % (11 / 3))  # 3.667
print('%.2f' % (11 / 3))  # 3.67
# Old-style rounding of decimals

However, this approach is quite old-fashioned and we do not encourage you to write code like this; in the past, it needed certainty in specifiers, length modifiers, and conversion types. The vast number of extra operators often caused common errors. That's why more user-friendly operators were introduced.

str.format()

One of them is the built-in str.format() method. Let's see how it can help us deliver the same welcome message:

name = 'John'
age = 20
print('Hi, my name is {}, I am {} years old!'.format(name, age))  # a more modern formatting method

The curly braces in the string are placeholders where the format method inserts the corresponding variables. Notice how we used the age variable as it is, without converting it to str.

With empty placeholders, variables were substituted in the same order they were passed to the format() method. But, we can change the order and the number of occurrences by specifying the corresponding position inside curly braces:

print('{0} in the {1} by Frank Sinatra'.format('Strangers', 'Night'))
# prints 'Strangers in the Night by Frank Sinatra'

print('{1} in the {0} by Frank Sinatra'.format('Strangers', 'Night'))
# prints 'Night in the Strangers by Frank Sinatra'

print('{1} in the {0} by Frank Sinatra: {1}'.format('Strangers', 'Night'))
# prints 'Night in the Strangers by Frank Sinatra: Night'

print('{1} in the {0} by Frank Sinatra: {2}'.format('Strangers', 'Night'))
# IndexError

Remember, if you passed more variables to the format() method than needed, the extra ones would be ignored. On the other hand, if you provided fewer variables, you would get an IndexError.

The format() method is very flexible, letting you use keywords inside placeholders, like this:

print('The {movie} movie at {theatre} was {adjective}!'.format(movie='Star Wars',
                                                        adjective='incredible',
                                                        theatre='BFI IMAX'))

This improves your code readability. You can also arrange the keywords in any order, and place them after positional arguments:

print('The {0} was {adjective}!'.format('Lord of the Rings', adjective='incredible'))
# The Lord of the Rings was incredible!

print('The {0} was {adjective}!'.format(adjective='incredible', 'Lord of the Rings'))
# SyntaxError: positional argument follows keyword argument

Formatted string literals

Another method to format strings in Python is f-strings. To create one, you need to put an 'f' before the string. Look at our welcome message from earlier:

name = 'John'
age = 20
print(f'Hi, my name is {name}, I am {age} years old!')  # another good approach to formatting strings

As you see, f-strings let you use the format() method's functionality, but the code turns out to be shorter and cleaner.

You can also round decimals with f-strings by specifying the number of decimal places like this:

decimal_number = 291.68
print(f'Decimal number as is: {decimal_number}')
# Decimal number as is: 291.68

print(f'Decimal number rounded to 1 decimal place: {decimal_number:.1f}')  # a clean way of rounding decimals
# Decimal number rounded to 1 decimal place: 291.7

Conclusion

What are the key points to remember from this topic? Here are two essential takeaways:

  • The str.format() method lets you customize string formatting;

  • Formatted string literals, or f-strings, excel in being brief and clear.

Read more on this topic in Working with Python Strings on Hyperskill Blog.

1716 learners liked this piece of theory. 50 didn't like it. What about you?
Report a typo