Anatomy of String Formatting

Python is a modern scripting language, so it offers us a flexible and readable coding. Therefore, we can do one thing in many different ways. That’s why until now we have even 4 main methods to format a string:

In this post, we walk through every style of string formatting, do an example for each style, and get understand how it works.

At the end of this post, we understand well everything about the string formatting methods in Python. And hopefully, it will help you well in your next Python project.

1. Classic Style String Formatting

So why this method is called as a classic style. Because it’s simple and the very first method to format a string in Python. It’s quite sure that every Python developer is used.

Its syntax quite similar to C-Style, where we use a % operator to receive arguments.

>>> my_name = "Mark"
>>> "My name is, %s" % my_name
'My name is, Mark'

The % operator let Python know to use the variable, in my example is my_name, to fill in the placeholder where is marked by %s.

One of the pros of this method is we can use % operator to control the data type that argument should be converted to. For example, %s means convert to string, %x converts to hexadecimal number. You can refer the printf-style document for more conversion type.

We are able to pass various variables into a string.

>>> print("My name: %s. My id: %d" % ("Bob", 1234))
My name: Bob. My id: 1234

The above syntax looks simple but becomes complicated and hard to maintain in case we have a large number of variables. We have to take care of the order of variables to make sure that the string is correct.

To avoid it, We should use a dictionary after % operator. If found the variable in the dictionary, it will fill in the string. Otherwise, we get a KeyError exception.

>>> print("My name: %(my_name)s. My id: %(my_id)d" % {"my_name": "Bob", "my_id": 1234})
My name: Bob. My id: 1234

Many developers comment that this old-style string formatting lack of flexibility to format a complicated string, hard to maintain, and can’t reuse it. And Python foundation did hear their voice, they introduce a modern-style string formatting in Python 3.

>>> Related post that you may love: Python Pandas for Beginners – A Complete Guide

2. Modern Style String Formatting (str.format)

In modern-style string formatting, we will use a built-in string function .format() instead of an operator.

>>> my_name = "Foo"
>>> 'Hello, my name is {}'.format(my_name)
'Hello, my name is Foo'

Now we call str.format to format a string. So you can do simple formatting with only one argument such as the above example. Or you even do a more complicated string formatting by using key-value pairs.

>> 'Hello, my name is {my_name}. I am {my_age} years old'.format(my_name = "Foo", my_age = 25)
'Hello, my name is Foo. I am 25 years old'

This is quite useful when we can change the order of arguments in the string regardless of the order of key-value pairs. This is a powerful feature that offers flexibility and maintainability to your string formatting.

So I’m sure that many of you will need to format the data type of arguments like the old-style support. And the good news is it’s still supported in the modern style.

>>> 'Hello, my name is {my_name:s}. I am {my_age:d} years old'.format(my_name = "Foo", my_age = 25)
'Hello, my name is Foo. I am 25 years old'

We added a format spec as a suffix of argument name. In the example, we use :s to format a string and :d to format a number.

Format spec allows you to define how each individual value present in the format string. Python supports many options here to make a flexible and even most complicated string in programming.

I will assume that you know the simple options, so I will describe some options that you rarely see while coding, or maybe you don’t know it exists. Anytime, you would like to reference more detail any format spec options, you can follow the link Format Specification Mini-Language.

Text Alignment With Modern Style

Example of using an option < for left-aligned, it also a default for alignment. Vice versa, we can use > for right-aligned.

>>> '{:<30}'.format('left aligned')
'left aligned                  '
>>> '{:>30}'.format('right aligned')
'                 right aligned'
>>> '{:<30} {:>30}'.format('left aligned', 'right aligned')
'left aligned                                    right aligned'

You even make a beautiful string easily such as below

'{:+^30}'.format('centered')
'+++++++++++centered+++++++++++'

Here, we use a character + as a fill char. You can replace it with any character that you want.

Example of Handling Number in String

There are many commons case that every developer have to handle a number in a string at least one time in their life. With the modern style, it becomes easier than ever.

>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(91)
'int: 91;  hex: 0x5b;  oct: 0o133;  bin: 0b1011011'

You can convert a number to any base you want in only one line of code. It’s super easy and super handy.

>>> '{:,}'.format(1234567890)
'1,234,567,890'

Insert a separator into a large number is no problem as well.

>>> points = 19
>>> total = 22
>>> 'Correct answers: {:.2%}'.format(points/total)
'Correct answers: 86.36%'

Format a percent number.

>>> Related post that you may love: Generator And Yield Keyword In 5 Minutes

3. Latest Style String Formatting (f-Strings)

Introduced in Python 3.6, f-Strings is adding another option to format a string. This style lets you embedded any variable to the string, no more operator, no more format().

F-strings stands for “formatted strings” and also know as “String Interpolation”. It is an expression evaluated at runtime, not a constant variable. So that your string can change dynamically in runtime. This is a super-powerful feature that is added to Python string formatting.

Support f-strings doesn’t mean other styles will be deprecated, so don’t worry about the old version of your code.

Here we will go through some example of using f-strings

Simple Example

>>> f"Hello, My name is {name}. I'm {age}."
"Hello, My name is Foo. I'm 25."

This is a simple example to show you how to replace the old style by f-strings.

As you can see, the prefix f lets Python know this string is the new style, f-strings. With f-strings, you can put expression to string via curly braces. At runtime, Python will replace the expression by its output.

>>> f"{2 * 2}"
'4'

Expression Evaluation

As mention above, the expression inside f-strings will be evaluated at runtime. This means we can use either a simple expression such as the above example or more complicated expressions such as call a function or pre-processing a list, dictionary.

Because of evaluation in runtime, an expression is able to access not only the local variables but also global variables.

>>> def get_name():
...   return "Foo"
...
>>> f"Hello, My name is {get_name()}"
'Hello, My name is Foo'

Now I would like to print out all the positive numbers of a list. It can be done when combining f-strings and filter() function.

>>> my_list = [0, -5, 8, 15, 12, -1, -3]
>>> f"Positive numbers: {list(filter(lambda x: x > 0, my_list))}"
'Positive numbers: [8, 15, 12]'

>>> Related post that you may love: Python *args & **kwargs in depth

4. Standard Style String Formatting (Template Strings)

The last method to format a string in this post is the template string. Although it’s less power than other methods, in some specific situations, it becomes more useful than others.

We take a look at the simple example before going to a definition

>>> from string import Template
>>> t = Template("Hello, my name is $my_name")
>>> t.substitute(my_name="Foo")
'Hello, my name is Foo'

You see here that the Template strings provide simpler string substitutions where you can replace a defined variable inside a Template by your data.

This method is using frequently in the system that required to send emails to their customers. You can define the email template onetime, replace the variables by the user’s information, and send it.

Here is the sample to use Python String Template as a welcome message.

>>> from string import Template
>>> t = Template('Dear, $name! On behalf of Python Geeks, welcome you onboard!')
>>> users = ["Mark", "David", "Hen"]
>>> for user in users:
...     t.substitute(name=user)
...
'Dear, Mark! On behalf of Python Geeks, welcome you onboard!'
'Dear, David! On behalf of Python Geeks, welcome you onboard!'
'Dear, Hen! On behalf of Python Geeks, welcome you onboard!'

>>> You may love to know how to send email in Python

Conclusion

At the end of the post, you already know 4 differents string formatting methods in Python. I’m quite sure that you will have a question “which is the best method to use in your code”.

There is no right answer to this question. You should understand every method and choose the best for your circumstance. However, from my experiences, I suggest you use “Modern Style” if your Python version is under 3.6 and use f-Strings if your project is working on Python 3.6 and above.

The String Template will be very useful if you’re building a service/product that needs a dynamic template that you can change it dynamically in runtime.

Sharing is caring!