Printf-style String Formatting¶
Python has two styles of string formatting. In this video, I am going to cover the C-Style or Printf-style formatting. In the next video, I’ll go over the new-style formatting.
Formatting Operator¶
The %
operator, applied to numbers, means “modulo” – the remainder after
division. When applied to strings or bytes, it means to perform the
printf-style formatting with the value that follows.
The value that follows may be:
A tuple of values.
A dictionary.
A single value.
The allowable types following the %
operator depend on what type of %
escapes exist in the string or byte.
If mapping keys are used, then it requires a dictionary.
If multiple substitutions are used, then a tuple with that many values is required.
If only one substitution is used, then a single value or a tuple with a single value is required.
Typically, the %
-escapes are very simple: %s
, %d
, %f
, etc…
and most of the time this is all you need. However, there are a number of
options that allow you to get creative with how you substitute values in.
You may optionally name the substitutions by following the
%
with(key name)
. If you are formatting a string, then the key will be a string. If you are formatting a bytes object, then the key will be a bytes object. Note that either ALL of the substitutions must have a key name or none of them can have it. You’ll get a TypeError if you are not consistent in either using key names or not.Following the name, you may have one or more conversion flags, which have a special meaning depending on the type of the substitition, These are
#
,0
,-
, space, and+
. -#
means to use the alternate form. Each type has its own alternateform.
0
will pad numbers with zeroes to fill up the space.-
will format the substitution to the left rather than the right, leaving space at the end to fill up the minimum space.space will leave a space for positive numbers, so that it aligns with negative numbers.
+
will force the+
sign to appear for positive numbers. (Negative numbers will always have a-
.)
After the optional conversion flags, you may specify how much space, minimum, to allocate for the value when it is substituted in. If you use a
*
, then it will read in the next value to determine how much space to leave.After the optional minimum field width, you can specify the precision. This is done with a
.
followed by a number. If you use a*
for the number, then the precision is read in from the next value in the tuple.After the precision, you can include a “length modifier”, which is
h
,l
, orL
. This means nothing to Python, but it is used in C/C++ to handle “long” integers or floats.Finally, you must specify a conversion type. One of the following letters must be used:
d
,i
,u
: Signed decimal integer. (u
typically means unsigned, but Python ignores this. Everything is signed.)o
: Signed octal integer. With the alternate form#
, prepends a0o
.x
: Lower-case hexadecimal. With the alternate form#
, prepends a0x
.X
: Upper-case hexadecimal. With the alternate form#
, prepends a0X
.e
: Lower-case floating point exponential form. The alternate form#
always contains a decimal point. The precision describes how many digits after the decimal point, and defaults to 0.E
: Same fore
but uses an upper-caseE
.f
ofF
: FLoating-point decimal format. It will not use thee
form. If not, then it usese
. Alternate form forces a decimal point. Precision describes how many digits after the decimal point to include.g
: Usese
if the exponent is less than-4
or not less than the precision, usesf
otherwise. Alternate form always includes the decimal. Trailing zeroes are also not removed. The precision determines the number of significant digits to use.G
: Same asg
but capitalE
when needed.c
: Single character.r
:repr(value)
. Precision truncates.s
:str(value)
. Precision truncates.a
:ascii(value)
. Precision truncates.
Integers¶
Let’s walk through some practical examples.
Suppose we want to format some integers, This is rather simple:
>>> "%d %d %d" % (1, -500, 700000)
'1 -500 700000'
If we want to get them to align, we’ll need to set a minimum space:
>>> "|%10d|%10d|%10d|" % (1, -500, 700000)
'| 1| -500| 700000|'
If a number were to exceed those bounds, that would be bad and throw off the formatting.
We can force the positive sign to appear:
>>> "|%+10d|%+10d|%+10d|" % (1, -500, 700000)
'| +1| -500| +700000|'
We can pad with zeros:
>>> "|%0+10d|%0+10d|%0+10d|" % (1, -500, 700000)
'|+000000001|-000000500|+000700000|'
Or left align:
>>> "|%-+10d|%-+10d|%-+10d|" % (1, -500, 700000)
'|+1 |-500 |+700000 |'
Making room for the negative signs:
>>> "|%- 10d|%- 10d|%- 10d|" % (1, -500, 700000)
'| 1 |-500 | 700000 |'
We can show hexadecimal numbers:
>>> "|%#10x|%#10x|%#10x|" % (1, -500, 700000)
'| 0x1| -0x1f4| 0xaae60|'
Pad them with zeroes:
>>> "|%#010x|%#010x|%#010x|" % (1, -500, 700000)
'|0x00000001|-0x00001f4|0x000aae60|'
Leave room for minus signs:
>>> "|%#0 10x|%#0 10x|%#0 10x|" % (1, -500, 700000)
'| 0x0000001|-0x00001f4| 0x00aae60|'
And you can do the same for octal!
Floats¶
Formatting floats depends on how big or small your numbers are.
For “regular” numbers,
%f
is probably fine.%10.3f
will give you 10 total spaces, 3 of them after the decimal point.For “scientific” numbers, that may vary by a large amount, either use
%e
or%g
.%e
always shows thee
, whileg
will avoid it if it can. Note that the precision is the number of significant figures, so if you’re really doing science,%g
is what you’re looking for.