The When of Python Blog

Guidance on when to use Python features (and when not to).
Comment your opinions on our articles to join the discussion.
Follow us on Twitter and GitHub to get the latest updates first.

String Theory


What has your experience of working with strings, especially f-strings, been? Do you agree with this post? Do you disagree? Please comment below.

Concatenation, Gluing, and Interpolation

Concatenation is one of the first ways we learn of joining strings together in Python, and it remains useful for simple cases, even when we learn about more sophisticated alternatives:

fname = 'Jo'
print('Hello ' + fname)

'Hello Jo'

Glueing, or joining strings together with a glue string, is especially useful when working with a sequence of items we wish to present together:

print(' \N{WHITE HEART} '.join(['Romeo', 'Juliet']))

'Romeo 🤍 Juliet'

In version 3.6, Python introduced formatted string literals, better known as f-strings. These make it possible to inject, or interpolate, other strings inside a larger string(1). f-strings are more readable than the alternative approaches Python had used earlier - namely sprint and the format method.

## sprint
fname = 'Elon'
print("Hello %s" % fname)

'Hello Elon'

lname = 'Musk'
print("Hello %s %s" % (fname, lname))

'Hello Elon Musk'

## format
print("Hello {fname} {lname}".format(fname=fname, lname=lname))
print("{unit_id:0>10}".format(unit_id="ABC1234"))  ## just showing how powerful the format method can become

'Hello Elon Musk'

'000ABC1234'

## f-string
fname = 'Elon'
lname = 'Musk'
print(f"{fname} {lname}")

'Elon Musk'

When Not to Use f-string Interpolation

The first question is whether interpolation should be used at all. Sometimes there is a more elegant solution using string methods.

word = 'crocodile'

## f-string overkill
print(f"{word:*^30}")

## semantic string method
print(word.center(30, '*'))

'**********crocodile***********'

'**********crocodile***********'

In other cases interpolation of any sort is not a good idea from a security point of view. If strings are being built from variables which in any way come from user input they open up vulnerabilities like SQL injection attacks. Here is the warning from the older psycopg docs: “Never, never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string. Not even at gunpoint.” And in newer documentation it says:

Don’t manually merge values to a query: hackers from a foreign country will break into your computer and steal not only your disks, but also your cds, leaving you only with the three most embarrassing records you ever bought. On cassette tapes. If you use the % operator to merge values to a query, con artists will seduce your cat, who will run away taking your credit card and your sunglasses with them. If you use + to merge a textual value to a string, bad guys in balaclava will find their way to your fridge, drink all your beer, and leave your toilet seat up and your toilet paper in the wrong orientation. You don’t want to manually merge values to a query: use the provided methods instead. Passing parameters to SQL queries

Even if interpolation is appropriate, it will sometimes be best to use an alternative to f-strings. The main situation in which it makes sense to use sprint or the format method instead is when the main string contains lots of curly braces and it is inefficient to escape all of them. And template strings might be best for untrusted user input Python String Formatting Best Practices

f-string Tips (Format Strings)

f-strings have a mini formatting language. Here are four useful tricks (for more, see Python F-String Codes I Use Every Day ):

Zero-Padding

a = 12345
print(f"{a:0>10}")

'0000012345'

Commas in Numbers

print(f"{a:,}")

'12,345'

Percentages

num = 0.5
print(f"{num:.0%}")

'50%'

Dates

from datetime import datetime
print(f"{datetime.today():%Y-%m-%d}")

'2024-04-21'

  1. or expressions resulting in strings, or anything which has a __str__ method ↩