Publish AI, ML & data-science insights to a global community of data professionals.

Python Template String Formatting Method

Details on Template string, an option to format strings in python. It can be more suitable when working with regex

Template string is another method used to format strings in Python. In comparison with %operator, .format() and f-strings, it has a (arguably) simpler syntax and functionality. It’s ideal for internationalization (i18n), and there are some nuances that you may find advantageous—especially when working with regular expressions (regex).

Let’s first see the syntax of the other three, so we can compare.

% operator

>>> name = "Alfredo"
>>> age = 40
>>> "Hello, %s. You are %s." % (name, age)
'Hello, Alfredo. You are 40.'

.format()

>>> print('The {} {} {}'.format('car','yellow','fast')) #empty braces
The car yellow fast
>>> print('The {2} {1} {0}'.format('car','yellow','fast')) #index
The fast yellow car
>>> print('The {f} {y} {c}'.format(c='car',y='yellow',f='fast')) #keywords
The fast yellow car

f-strings

>>> name = "Peter"
>>> print(f'Nice to meet you, {name}')

Template string

It uses Template class from string module. It has a syntax somewhat similar to .format() when done with keywords, but instead of curly braces to define the placeholder, it utilises a dollar sign ($). ${} is also valid and should be in place when a valid string comes after the placeholder.

See the syntax for various situations. I’ll begin explaining safe_substitute and the use with regex.

safe_substitute and Regex

Imagine you want to replace something in a string that contains {}, % and $. It can happen when working with regular expression.

Consider an input field that accepts company stock symbol plus positive (+) or negative (-) values in percentages and nothing afterwards. And symbol plus +- is dynamically replaced. Such as: AAPL: +20% or TSLA: -5% (Perhaps it’s a silly use case, I know! but please ignore. It’s just an example).

Regex: (([symbol: + or -][0–9]{1,4}[%])$)

For % operator, .format() and f-string – it doesn’twork. % operator and .format() raises an error and f-strings removes {m,n}. See below

#% operator
>>> print('(([%s][0-9]{1,4}[%])$)' % "AAPL: -")
TypeError: not enough arguments for format string
#.format()
>>> print('(([{symbol_pos_neg}][0-9]{1,4}[%])$)'.format(symbol_pos_neg = 'AAPL: +'))
KeyError: '1,4'
#f-strings
>>> symbol_pos_neg = "AAPL: +"
>>> print(f'(([{symbol_pos_neg}][0-9]{1,4}[%])$)')
(([AAPL: +][0-9](1, 4)[%])$)

Although it can be easily solved by escaping the characters (doubling the curly braces or percentage sign), I find it inconvenient. With Template string, you don’t need to do that. {} and % are not used to define placeholders, and by using safe_substitute, you’re not enforced to replace all $.

See below, the regex is unchanged and $symbol_pos_neg is replaced correctly.

>>> print(Template('(([$symbol_pos_neg][0-9]{1,4}[%])$)').safe_substitute(symbol_pos_neg='AAPL: -'))
(([AAPL: -][0-9]{1,4}[%])$)

Regular case with keyword

>>> from string import Template
>>> Template('$obj is $colour').substitute(obj='Car',colour='red')
'Car is red'

Regular case with a dictionary

>>> d = dict(obj='Car')
>>> Template('$obj is red').substitute(d)
'Car is red'

Placeholder followed by an invalid character

If there is an invalid string after the placeholder, only the placeholder is considered. Example, see the ‘.’ (dot) after $who. It’s printed as normal.

>>> from string import Template
>>> Template('$obj. is $colour').substitute(obj='Car',colour='red')
'Car. is red'

Placeholder followed by a valid character

If valid characters follow the placeholder, it must be enclosed in curly braces.

>>> from string import Template
>>> Template('${noun}ification').substitute(noun='Ident')
'Identification'

To note, characters such as underscore (_) is also considered valid. So the same rule to use ${} applies.

Multiple $$$ signs

The substitution is done as normal, and one extra $ is printed.

>>> Template('$obj. is $$$colour').substitute(obj='Car',colour='red')
'Car. is $red'

Final Thoughts

I’m still a beginner in Python and comparing String formatting methods taught me a lot. I hope I was clear in providing the details to you. Despite Template string being less powerful:

viniciusmonteiro$ python3 -m timeit -s "x = 'f'; y = 'z'" "f'{x} {y}'"
5000000 loops, best of 5: 82.5 nsec per loop
viniciusmonteiro$ python3 -m timeit -s "from string import Template; x = 'f'; y = 'z'" "Template('$x $y').substitute(x=x, y=y)"  # template string
500000 loops, best of 5: 752 nsec per loop

I think it brings some benefit in terms of simplicity and convenience in some cases. Although I understand these can be subjective.

Reference

[1] [string](https://docs.python.org/3/library/string.html#module-string) – Common string operations https://docs.python.org/3/library/string.html#template-strings

[2] Python 3’s f-Strings: An Improved String Formatting Syntax (Guide) https://realpython.com/python-f-strings/

[3] Performance of different string concatenation methods in Python – why f-strings are awesome https://grski.pl/fstrings-performance.html


Towards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program.

Write for TDS

Related Articles