String Formatting Expressions

Although you can get a lot done with the string methods and sequence operations we’ve already met, Python also provides a more advanced way to combine string processing tasks—string formatting allows us to perform multiple type-specific substitutions on a string in a single step. It’s never strictly required, but it can be convenient, especially when formatting text to be displayed to a program’s users. Due to the wealth of new ideas in the Python world, string formatting is available in two flavors in Python today (not counting the less-used string module Template system mentioned in the prior section):

String formatting expressions: '...%s...' % (values)

The original technique available since Python’s inception, this form is based upon the C language’s “printf” model, and sees widespread use in much existing code.

String formatting method calls: '...{}...'.format(values)

A newer technique added in Python 2.6 and 3.0, this form is derived in part from a same-named tool in C#/.NET, and overlaps with string formatting expression functionality.

Since the method call flavor is newer, there is some chance that one or the other of these may become deprecated and removed over time. When 3.0 was released in 2008, the expression seemed more likely to be deprecated in later Python releases. Indeed, 3.0’s documentation threatened deprecation in 3.1 and removal thereafter. This hasn’t happened as of 2013 and 3.3, and now looks unlikely given the expression’s wide use—in fact, it still appears even in Python’s own standard library thousands of times today!

Naturally, this story’s development depends on the future practice of Python’s users. On the other hand, because both the expression and method are valid to use today and either may appear in code you’ll come across, this book covers both techniques in full here. As you’ll see, the two are largely variations on a theme, though the method has some extra features (such as thousands separators), and the expression is often more concise and seems second nature to most Python programmers.

This book itself uses both techniques in later examples for illustrative purposes. If its author has a preference, he will keep it largely classified, except to quote from Python’s import this motto:

There should be one—and preferably only one—obvious way to do it.

Unless the newer string formatting method is compellingly better than the original and widely used expression, its doubling of Python programmers’ knowledge base requirements in this domain seems unwarranted—and even un-Pythonic, per the original and longstanding meaning of that term. Programmers should not have to learn two complicated tools if those tools largely overlap. You’ll have to judge for yourself whether formatting merits the added language heft, of course, so let’s give both a fair hearing.

Formatting Expression Basics

Since string formatting expressions are the original in this department, we’ll start with them. Python defines the % binary operator to work on strings (you may recall that this is also the remainder of division, or modulus, operator for numbers). When applied to strings, the % operator provides a simple way to format values as strings according to a format definition. In short, the % operator provides a compact way to code multiple string substitutions all at once, instead of building and concatenating parts individually.

To format strings:

  1. On the left of the % operator, provide a format string containing one or more embedded conversion targets, each of which starts with a % (e.g., %d).

  2. On the right of the % operator, provide the object (or objects, embedded in a tuple) that you want Python to insert into the format string on the left in place of the conversion target (or targets).

For instance, in the formatting example we saw earlier in this chapter, the integer 1 replaces the %d in the format string on the left, and the string 'dead' replaces the %s. The result is a new string that reflects these two substitutions, which may be printed or saved for use in other roles:

>>> 'That is %d %s bird!' % (1, 'dead')             # Format expression
That is 1 dead bird!

Technically speaking, string formatting expressions are usually optional—you can generally do similar work with multiple concatenations and conversions. However, formatting allows us to combine many steps into a single operation. It’s powerful enough to warrant a few more examples:

>>> exclamation = 'Ni'
>>> 'The knights who say %s!' % exclamation         # String substitution
'The knights who say Ni!'

>>> '%d %s %g you' % (1, 'spam', 4.0)               # Type-specific substitutions
'1 spam 4 you'

>>> '%s -- %s -- %s' % (42, 3.14159, [1, 2, 3])     # All types match a %s target
'42 -- 3.14159 -- [1, 2, 3]'

The first example here plugs the string 'Ni' into the target on the left, replacing the %s marker. In the second example, three values are inserted into the target string. Note that when you’re inserting more than one value, you need to group the values on the right in parentheses (i.e., put them in a tuple). The % formatting expression operator expects either a single item or a tuple of one or more items on its right side.

The third example again inserts three values—an integer, a floating-point object, and a list object—but notice that all of the targets on the left are %s, which stands for conversion to string. As every type of object can be converted to a string (the one used when printing), every object type works with the %s conversion code. Because of this, unless you will be doing some special formatting, %s is often the only code you need to remember for the formatting expression.

Again, keep in mind that formatting always makes a new string, rather than changing the string on the left; because strings are immutable, it must work this way. As before, assign the result to a variable name if you need to retain it.

Advanced Formatting Expression Syntax

For more advanced type-specific formatting, you can use any of the conversion type codes listed in Table 7-4 in formatting expressions; they appear after the % character in substitution targets. C programmers will recognize most of these because Python string formatting supports all the usual C printf format codes (but returns the result, instead of displaying it, like printf). Some of the format codes in the table provide alternative ways to format the same type; for instance, %e, %f, and %g provide alternative ways to format floating-point numbers.

Table 7-4. String formatting type codes

Code

Meaning

s

String (or any object’s str(X) string)

r

Same as s, but uses repr, not str

c

Character (int or str)

d

Decimal (base-10 integer)

i

Integer

u

Same as d (obsolete: no longer unsigned)

o

Octal integer (base 8)

x

Hex integer (base 16)

X

Same as x, but with uppercase letters

e

Floating point with exponent, lowercase

E

Same as e, but uses uppercase letters

f

Floating-point decimal

F

Same as f, but uses uppercase letters

g

Floating-point e or f

G

Floating-point E or F

%

Literal % (coded as %%)

In fact, conversion targets in the format string on the expression’s left side support a variety of conversion operations with a fairly sophisticated syntax all their own. The general structure of conversion targets looks like this:

%[(keyname)][flags][width][.precision]typecode

The type code characters in the first column of Table 7-4 show up at the end of this target string’s format. Between the % and the type code character, you can do any of the following:

  • Provide a key name for indexing the dictionary used on the right side of the expression

  • List flags that specify things like left justification (), numeric sign (+), a blank before positive numbers and a for negatives (a space), and zero fills (0)

  • Give a total minimum field width for the substituted text

  • Set the number of digits (precision) to display after a decimal point for floating-point numbers

Both the width and precision parts can also be coded as a * to specify that they should take their values from the next item in the input values on the expression’s right side (useful when this isn’t known until runtime). And if you don’t need any of these extra tools, a simple %s in the format string will be replaced by the corresponding value’s default print string, regardless of its type.

Advanced Formatting Expression Examples

Formatting target syntax is documented in full in the Python standard manuals and reference texts, but to demonstrate common usage, let’s look at a few examples. This one formats integers by default, and then in a six-character field with left justification and zero padding:

>>> x = 1234
>>> res = 'integers: ...%d...%−6d...%06d' % (x, x, x)
>>> res
'integers: ...1234...1234  ...001234'

The %e, %f, and %g formats display floating-point numbers in different ways, as the following interaction demonstrates—%E is the same as %e but the exponent is uppercase, and g chooses formats by number content (it’s formally defined to use exponential format e if the exponent is less than −4 or not less than precision, and decimal format f otherwise, with a default total digits precision of 6):

>>> x = 1.23456789
>>> x                                     # Shows more digits before 2.7 and 3.1
1.23456789

>>> '%e | %f | %g' % (x, x, x)
'1.234568e+00 | 1.234568 | 1.23457'

>>> '%E' % x
'1.234568E+00'

For floating-point numbers, you can achieve a variety of additional formatting effects by specifying left justification, zero padding, numeric signs, total field width, and digits after the decimal point. For simpler tasks, you might get by with simply converting to strings with a %s format expression or the str built-in function shown earlier:

>>> '%−6.2f | %05.2f | %+06.1f' % (x, x, x)
'1.23   | 01.23 | +001.2'

>>> '%s' % x, str(x)
('1.23456789', '1.23456789')

When sizes are not known until runtime, you can use a computed width and precision by specifying them with a * in the format string to force their values to be taken from the next item in the inputs to the right of the % operator—the 4 in the tuple here gives precision:

>>> '%f, %.2f, %.*f' % (1/3.0, 1/3.0, 4, 1/3.0)
'0.333333, 0.33, 0.3333'

If you’re interested in this feature, experiment with some of these examples and operations on your own for more insight.

Dictionary-Based Formatting Expressions

As a more advanced extension, string formatting also allows conversion targets on the left to refer to the keys in a dictionary coded on the right and fetch the corresponding values. This opens the door to using formatting as a sort of template tool. We’ve only met dictionaries briefly thus far in Chapter 4, but here’s an example that demonstrates the basics:

>>> '%(qty)d more %(food)s' % {'qty': 1, 'food': 'spam'}
'1 more spam'

Here, the (qty) and (food) in the format string on the left refer to keys in the dictionary literal on the right and fetch their associated values. Programs that generate text such as HTML or XML often use this technique—you can build up a dictionary of values and substitute them all at once with a single formatting expression that uses key-based references (notice the first comment is above the triple quote so it’s not added to the string, and I’m typing this in IDLE without a “...” prompt for continuation lines):

>>>                                           # Template with substitution targets
>>> reply = """
Greetings...
Hello %(name)s!
Your age is %(age)s
"""
>>> values = {'name': 'Bob', 'age': 40}       # Build up values to substitute
>>> print(reply % values)                     # Perform substitutions

Greetings...
Hello Bob!
Your age is 40

This trick is also used in conjunction with the vars built-in function, which returns a dictionary containing all the variables that exist in the place it is called:

>>> food = 'spam'
>>> qty = 10
>>> vars()
{'food': 'spam', 'qty': 10, ...plus built-in names set by Python... }

When used on the right side of a format operation, this allows the format string to refer to variables by name—as dictionary keys:

>>> '%(qty)d more %(food)s' % vars()          # Variables are keys in vars()
'10 more spam'

We’ll study dictionaries in more depth in Chapter 8. See also Chapter 5 for examples that convert to hexadecimal and octal number strings with the %x and %o formatting expression target codes, which we won’t repeat here. Additional formatting expression examples also appear ahead as comparisons to the formatting method—this chapter’s next and final string topic.