3 ways to format a string¶
Here is an example of this 3 ways to include data in a string:
name = 'John'
age = 25
"My name is %s, I am %d." % (name, age) # % way
"My name is {n}, I am {a}.".format(n=name, a=age) # format way
f"My name is {name}, I am {age}." # f way
They all display:
My name is John, I am 25.
The second goal of formatting it to display data as you want. We will see how to do that.
The % way¶
This is the original way of formatting in Python. It is powerful but restricted to:
- int
- float
- string
You can use any other type as long it can be converted to a string:
print("The list %s is small" % [1,2,3])
The list [1, 2, 3] is small
If something cannot be converting to an int, float or string, you cannot print it this way (it does not happen often).
Formating with the % way¶
Numericals¶
Since we don't want to see accounting in the same way than scientific data, even if the computer store them in the same way, let explain it to Python to get what we want:
x = 1200
y = 6.022140857E23
print("My portfolio value is %+.2f €" % x)
print("Avogadro constant is %.3E mol⁻¹" % y)
My portfolio value is +1200.00 € Avogadro constant is 6.022E+23 mol⁻¹
As you guessed, the value replace the part of the string with %...f
(for floating format) or %...E
(for scientific notation) by the argument after the %
after the string.
If there is more than one place to be replaced in the string, then you should give a tuple of values as argument (see first exemple with John).
Here is a summary of the rules of formatting for integer (with 'd' as digit) and floats:
Format string | Result | Explanation |
---|---|---|
'%3d' % 2 |
' 2' |
we book at least 3 spaces |
'%3d' % 12345 |
'12345' |
|
'%*d' % (3, 2) |
' 2' |
get # of space + value from argument |
'%-3d' % 2 |
'2 ' |
3 space value left aligned |
'%03d' % 2 |
'002' |
fill spaces with 0 |
'% d' % 2 |
' 2' |
a space for sign and the value |
'%+d' % 2 |
'+2' |
sign and value |
'%+3d' % -2 |
' -2' |
|
'%.4f' % 2 |
'2.0000' |
4 digits after the dot |
'%.*f' % (4, 2) |
'2.0000' |
get # of digits after the dot from arg |
'%10.4f' % 2 |
' 2.0000' |
10 spaces, 4 digits after dot |
'%010.4f' % 2 |
'00002.0000' |
same as previous but filled with 0 |
'%0*.*f' % (10, 4, 2) |
'00002.0000' |
The end letter of the format string can be:
Letter | Meanning |
---|---|
d | Signed integer decimal. |
i | Signed integer decimal. |
o | Unsigned octal. |
u | Unsigned decimal. |
x | Unsigned hexadecimal (lowercase). |
X | Unsigned hexadecimal (uppercase). |
e | Floating point exponential format (lowercase). |
E | Floating point exponential format (uppercase). |
f | Floating point decimal format. |
F | Floating point decimal format. |
g | Same as "e" if exponent is greater than -4 or less than precision, "f" otherwise. |
G | Same as "E" if exponent is greater than -4 or less than precision, "F" otherwise. |
c | Single character (accepts integer or single character string). |
r | String (converts any python object using repr()). |
s | String (converts any python object using str()). |
% | No argument is converted, results in a "%" character in the result. (The complete specification is %%.) |
String¶
Even strings may need to be formatted to display something nice. See how names are left-justified and trunked if too long:
math_exam = {'Alice':12.5, 'Alexandre':16, 'Bob':11, 'AVeryVeryLongName':5}
for n,m in math_exam.items():
print("%-11.10s has %4.1f/20" % (n,m))
Alice has 12.5/20 Alexandre has 16.0/20 Bob has 11.0/20 AVeryVeryL has 5.0/20
where %-11.10s
means:
- %: begin format
- s: a string (ends format too)
- 11: attribute 11 spaces min
- .10: make it 10 chars max
- -: left-justified
The f way¶
When you know the % format, the f format is easy. All you have to do is to replace '%3.1d' % x
by f'{x:3.1d}'
which is
- more compact,
- easier to read since the variable and its format are together
- without argument after the string
Our previous exemple is now:
for n,m in math_exam.items():
print(f"{n:<11.10s} has {m:4.1f}/20")
Alice has 12.5/20 Alexandre has 16.0/20 Bob has 11.0/20 AVeryVeryL has 5.0/20
Note that the we already get an exception to the just replace rule. Left justification is <
and not anymore -
(right is >
and center is ^
).
The value can be any math operation or complex operation:
import math
x = 2
f"Square root of {x} is {math.sqrt(x):.4f}"
'Square root of 2 is 1.4142'
An f string can also be with a '''
for text on many lignes (note the return, \n
, which becomes a new
line when printed).
text = f'''
a = {2+2}
b = {7.432:.1f}
'''
print(text)
text
a = 4 b = 7.4
'\na = 4\nb = 7.4\n'
Here is a full description of the format string syntax.
Exercice¶
Guess the output of these cells:
'a'+'b'+f'{10+5}'+'{20%3}'+f'str<{"hi":^4}>'+'d'+'e'
'ab15{20%3}str< hi >de'
f'{list({x%3 for x in range(10)})}'
'[0, 1, 2]'
What about the format way?¶
The f way has been introduced in Python 3.6 and I beleive it is better than the format way, so no real need to learn the format way.
However here is a description in few words:
- the string structure is the same than in the f way if you name the variables
- the real variables are arguments of the
format
method (a method of the String class) - you can use numbers in the string format to refer to arguments
name = 'John'
mark = 16.78
print("The mark of {n} is {m:.1f}.".format(n=name, m=mark))
print("The mark of {0} is {1}.".format(name, mark))
The mark of John is 16.8. The mark of John is 16.78.
{{ PreviousNext("02 - La porté des variables.ipynb", "04 - Generators.ipynb")}}