Python String Formatting

Right now, str.format is probably the best way to accomplish most string formatting in Python.

I'm not going to touch on the format spec mini-language, because I've never learned it and frankly never needed to. I'm also making sure that everything works with Python 3.4 and up, unless otherwise noted.

N.B. This is a work in progress, so I might have missed something.

str.format

This is the prevalent "best practice" way of formatting strings with values in Python. It works with any str, including literals:

It allows keyword arguments like "name" above to be interpolated into text strings.

Some caveats and tips:

  • In Python, strings with no separator between them (i.e. ignoring whitespace) are concatenated. The format function is applied after this concatenation:

  • If you have a dictionary like {str(name) : value}, you can expand that dictionary into keyword arguments using the double-splat operator:

  • The "replacement string" (i.e. bit inside the brackets) supports a few things that look like arbitrary Python:

This also works with dictionaries using strings for keys, but make sure not to include any quotes:

Unfortunately, this means you can't give .format a string and expect it to lookup that string in a dictionary. PEP 3101 has more details on why this is the case, and on limitations to the format syntax (it's Python-like, but very limited).

The replacement string isn't arbitrary Python, so don't try to call functions in it, and remember the special-case of dictionaries with string keys. If you need to lookup arbitrary string keys, call a function, or do anything remotely advanced, do it outside of the format string. (Even as an argument to .format, if you're bent on keeping it to one line!)

  • You can also refer to positional arguments passed to .format by using numbers:

Here, *notes is expanded to notes[0], notes[1], ... using the (single) splat operator.

  • If you know all your arguments are going to be passed in the right order -- or if there's just one -- you can skip the numbers altogether and use the automatic numbering system:

N.B. Don't mix manual and automatic numbering; it's a ValueError!

Other Methods

Python has far too many ways to format strings, for a language whose Zen says "There should be one, and preferably only one, obvious way to do it". Some other ways of doing it you might see include:

  • %-formatting
  • string.Template ($-formatting)
  • string.Formatter
  • Format-string literals (Python 3.6+)
  • print's comma-separated interpolation
  • Simple concatenation (+ operator)
  • binary string formatting

These all have their strengths and weaknesses. I for one think the %-formatting (common in 2.x code but still valid in 3.x) is as ugly as sin, but I see it absolutely everywhere -- just use whichever is applicable for your use-case.