Show Menu
Cheatography

Python F-Strings Number Formatting Cheat Sheet by

Contains formulas, tables, and examples showing patterns and options focused on number formatting for Python's Formatted String Literals -- i.e., F-Strings.

F-String Template

f" text {replacement_field} text ... "
Inside the quotes the f-string consists of two kinds of parts: (1) regular string literals, i.e., text, and (2) replac­ement fields containing Python expres­sions for evaluation along with formatting control.
Double quotes are used here but single or triple quotes could also be used.
F-strings may consist of just a replac­ement field:
 ­ ­ ­ ­ f"{r­epl­ace­men­t_f­iel­d}"

Replac­ement Field

{f-expression = !conversion:format_specifier}
A replac­ement field is signaled by a pair of curly braces: { }
A replac­ement field consists of a Python expression for evaluation with optional debugging mode (=), type conversion (!), and format specif­ication (:).
Substi­tuting into the f-string template:

f" text {f-exp­ression = !conve­rsi­on:­for­mat­_sp­eci­fier} text ..."

Format Specifier

:fill align sign # 0 width sep .precision type

Brief Summary of the Format Specif­ication Mini-L­anguage

fill : the padding character
align : alignment of text within the space
sign : how + and - are used preceding numbers
# : alternate presen­tation format for some number types
0 : sign-a­ware, zero-p­adding on numbers
width : the minimum total field width
sep : the separator character for numbers (',' or '_')
.precision : how many digits displayed for floats;
            maximum field width for strings
type : the type of presen­tation to use based on data type
Note: sign, #, 0, sep, precision, and type are of particular interest for number formatting, the focus of this cheats­heet. For a general treatment of F-Strings, see my cheatsheet Python F-Strings Basics.

Format Specifier: Options

fill
align
sign
0
width
sep
.prec
type
char
<
+
 
digit(s)
_
digit(s)
string: s
 
>
-
  
,
 
number: n
 
^
' '
    
integer: d, b, o, x, X, c
 
=
     
float: e, E, f, F, g, G, %

Sign and Separator Options

Sign
+
a sign is used for both positive and negative numbers
-
a sign is used only for negative numbers (default)
space
leading space for positive numbers and minus sign for negative
Separator
,
comma. decimal integers and floats: thousands separator
_
unders­core. decimal integers and floats: thousands separator; b, o, x, and X types: separates every four digits

Examples: Sign and Separator

# sign (+): a sign is attached to both positive and negative numbers
f"{3:+} or {-3:+}­"
'+3 or -3'
# sign (-): a sign is only used for negative numbers
f"{3:-} or {-3:-}­"
'3 or -3'
# no sign is the same as sign (-)
f"{3} or {-3}"
'3 or -3'
# sign (space): a leading space for positive numbers and a minus sign for negative
f"{3: } or {-3: }"
' 3 or -3'
# sign (+), separator (,)
f"{1­000­0:+­,}"
'+10,000'
# fill (?), align (<), sign (+), width (11), sep (,)
f"{1­000­0:?­<+1­1,}­"
'+10,0­00????'

Sign Aware Padding

Using the = alignment option forces the padding determined by the fill and width specif­ica­tions to be placed after the sign (if any) but before the digits. This is useful for number repres­ent­ations like '+000042'. This alignment option is only available for numeric types.
The 0-option produces sign aware zero-p­adding just like the = alignment option with a fill of '0'. It is produced by preceding the field width specif­ication with '0'.
# fill (?), align (=), sign (+), width (5)
f"{3­:?=­+5}­"
'+???3'
# fill (0), align (=), sign (+), width (5)
f"{3­:0=­+5}­"
'+0003'
# sign (+), 0-option, width (5)
f"{3­:+0­5}"
'+0003'
# 0-option, width (5)
f"{3­:05­}"
'00003'

Integer Presen­tation Types

Decimal Integer Types
d
Decimal Integer: the number in base 10
None
Same as d
n
Number. Same as d, except uses current locale setting for the approp­riate number separator character
Others
b
Binary: the number in base 2.
o
Octal: the number in base 8.
x, X
Hex: the number in base 16. x vs X signals lower vs upper case for digits > 9
c
Unicode Character. Converts decimal integer to the corres­ponding unicode character
#-option: using the #-option adds prefixes
 ­ ­ ­ ­ #b: adds prefix 0b ­ ­ ­ ­ ­ ­ ­ ­ ­ #o: adds prefix 0o
 ­ ­ ­ ­ #x: adds prefix 0x ­ ­ ­ ­ ­ ­ ­ ­ ­ #X: adds prefix 0X

Examples: Integer Types

i = 13
# repres­enting decimal 13 in binary, octal, and hexade­cimal
f"bi­nary: {i:b}; octal: {i:o}; hex: {i:x} or {i:X}"
 
'binary: 1101; octal: 15; hex: d or D'
# the #-option adds prefixes
f"bi­nary: {i:#b}; octal: {i:#o}; hex: {i:#x} or {i:#X}­"
 
'binary: 0b1101; octal: 0o15; hex: 0xd or 0XD'
# binary with zero padding
f"{i­:08­b}"
'00001101'
# binary with prefix and zero padding
f"{i­:#0­8b}­"
'0b001101'
# fill (0), align (=), #-option, width (8), type (b)
f"{i­:0=­#8b­}"
'0b001101'
# returns the unicode character with decimal repres­ent­ation 36
f"{3­6:c­}"
'$'
# printing symbols with unicode decimal repres­ent­ations 33-41
print(­''.j­oi­n([­f"{x­:c}­" for x in range(­33,­42)]))
 
!"#$­%&'()
# separator (,) and type (d)
f"{1­000­0:,­d}"
'10,000'
# type d is the default for integers, so unnece­ssary
f"{1­000­0:,­}"
'10,000'
# separator (_), type (b)
f"{1­200­:_b­}"
'100_1­011­_0000'
# to use locale specific number format­ting, set the locale
import locale
locale.se­tlo­cal­e(l­oca­le.L­C_ALL, '')
# then use format type 'n'
f"{1­0**­6:n­}"
'1,000­,000'
 

Float Presen­tation Types

Type
Name
For a given precision p...
e, E
Scientific Notation
The coeffi­cient has 1 digit before and p digits after the decimal point.
f, F
Fixed-­Point Notation
There are p digits following the decimal point.
g, G
General Format
Rounds number to p signif­icant digits, then formats in either fixed-­point or scientific notation depending on magnitude.
%
Percentage
Multiplies the number by 100 and displays in fixed f format, followed by a percent sign.
Default for float is p = 6. Default for decima­l.D­ecimal is p large enough to show all coeffi­cient digits.
Lower case versus upper case: Determines whether scientific notation shows 'e' or 'E' and whether to use 'nan' versus 'NAN' and 'inf' versus 'INF'.

Examples: Simple Float Compar­isons

# %-style with precis­ion=1
f"{1­/2:.1%­}"
'50.0%'
# Lower case e versus upper case E
f"{1­000­:.1e} vs {1000:.1E­}"
'1.0e+03 vs 1.0E+03'
# Lower case f versus upper case F
f"{1­000­:.1f} vs {1000:.1F­}"
'1000.0 vs 1000.0'
# Lower case g versus upper case G
f"{1­000­:.1g} vs {1000:.1G­}"
'1e+03 vs 1E+03'
# Lower versus upper case NaN repres­ent­ation
nan = float(­'nan')
f"{n­an:f} vs {nan:F­}"

'nan vs NAN'

General Format (g or G) Rule

Given the number y and the precision specif­ication p:
(a) Let exp = the exponent of y in scientific notation.
(b) Is -4 <= exp < p?
"­Yes­": Format y using fixed-­point notation and a new precision: p' = p - (1 + exp) where p represents the number of signif­icant digits before any trailing zeros are removed. (In fixed-­point format, the precision, here p', determines the number of digits following the decimal point. When it is positive, the value 1 + exp can be interp­reted as the total number of digits before the decimal; otherwise, it represents the total number of zeros after the decimal point but before the signif­icant digits.)
"­No": Format y using scientific notation and a new precision: p' = p - 1 where p represents the total number of signif­icant digits in the coeffi­cient before any trailing zeros are removed. (In scientific format, the precision determines the number of digits displayed after the decimal point of the coeffi­cient. So, the total number of digits displayed will be: precision + 1 = p' + 1 = p.)
(c) With the #-option (#g, #G): Keep any trailing zeros and the decimal point.
Without the #-option (g, G): If the result has insign­ificant trailing zeros, remove them as well as an unflanked decimal point.
Note: In both cases in (b), the original precision specif­ication p determines the effective number of signif­icant digits up until insign­ificant trailing zeros are removed in (c).

General Format (g or G): Illust­ration

#.4g
.4g
exp
format type
(keep trailing zeros)
(no trailing zeros)
 
1.000e-06
1e-06
-6
e
1.000e-05
1e-05
-5
e
0.0001000
0.0001
-4
f
0.001000
0.001
-3
f
0.01000
0.01
-2
f
0.1000
0.1
-1
f
1.000
1
0
f
10.00
10
1
f
100.0
100
2
f
1000.
1000
3
f
1.000e+04
1e+04
4
e
In this illust­ration, the precision specif­ication is p = 4; so, for exp from -4 to 3, fixed-­point notation (f) is used; otherwise, scientific notation (e) is used.

Types with Condit­ional Formatting

Type
Interp­ret­ation
g, G
= e or f (E or F) according to the General Format Rule
none
= s for strings
 
= d for integers
 
= g for floats
When fixed-­point notation is used, it always includes at least one digit past the decimal point. The precision varies to represent the given value faithf­ully.
n
= d for integers
 
= g for floats
Uses the current locale setting for separator format­ting.

Examples: Both Integers and Floats

si = 55  ­ # small integer
li = 666666  ­ # large integer
sf = 7.77777  ­ # small float
lf = 8888.88  ­ # large float
sc = 9e6  ­ # scientific notation
# none -- no type specified
f"{si} {li} {sf} {lf} {sc}"
'55  ­ ­666666  ­ ­7.77777  ­ ­8888.88  ­ ­900­0000.0'
# n -- number type
f"{si:n} {li:n} {sf:n} {lf:n} {sc:n}­"
'55  ­ ­666666  ­ ­7.77777  ­ ­8888.88  ­ ­9e+06'
# n with #-option
f"{s­i:#n} {li:#n} {sf:#n} {lf:#n} {sc:#n­}"
'55  ­ ­666666  ­ ­7.77777  ­ ­8888.88  ­ ­9.0­000­0e+06'
# n with precision = 3 (precision not allowed for integers)
f"{s­i:.3n} {li:.3n} {sf:.3n} {lf:.3n} {sc:.3­n}"
# e with precision = 3 (forces 3 digits after decimal point)
f"{s­i:.3e} {li:.3e} {sf:.3e} {lf:.3e} {sc:.3­e}"
# including the #-option gives the same result here
f"{s­i:#.3e} {li:#.3e} {sf:#.3e} {lf:#.3e}
{sc:#.3e}"
'5.500e+01  ­ ­6.6­67e+05  ­ ­7.7­78e+00  ­ ­8.8­89e+03  ­ ­9.0­00e+06'
# f with precision = 3 (forces 3 digits after decimal point)
f"{s­i:.3f} {li:.3f} {sf:.3f} {lf:.3f} {sc:.3­f}"
# including the #-option gives the same result here
f"{s­i:#.3f} {li:#.3f} {sf:#.3f} {lf:#.3f}
{sc:#.3f}"
'55.000  ­ ­666­666.000  ­ ­7.778  ­ ­888­8.880  ­ ­900­000­0.000'
# g with precision = 3 (shows no unnecesary zeros or decimal points)
f"{s­i:.3g} {li:.3g} {sf:.3g} {lf:.3g} {sc:.3­g}"
'55  ­ ­6.6­7e+05  ­ 7.78  ­ ­8.8­9e+03  ­ ­9e+06'
# g with #-option (forces showing 3 signif­icant digits)
f"{s­i:#.3g} {li:#.3g} {sf:#.3g} {lf:#.3g}
{sc:#.3g}"
'55.0  ­ ­6.6­7e+05  ­ 7.78  ­ ­8.8­9e+03  ­ ­9.0­0e+06'
# In float types generally, the #-option forces a decimal point occurrence even when no digits follow it
f"{1­0:#.0e} {10:#.0f} {10:#.0­g}­"
'1.e+01  ­ 10.  ­ ­1.e+01'

References

"­Python 3's f-Strings: An Improved String Formatting Syntax (Guide­)" by Joanna Jablonski at Real Python: https:­//r­eal­pyt­hon.co­m/p­yth­on-­f-s­trings/
"­Format String Syntax­" including "­Format Specif­ication Mini-L­ang­uag­e" from the page "string -- Common string operat­ion­s": https:­//d­ocs.py­tho­n.o­rg/­3/l­ibr­ary­/st­rin­g.h­tml­#fo­rma­t-s­tri­ng-­syntax
"PEP 498 -- Literal String Interp­ola­tio­n": https:­//w­ww.p­yt­hon.or­g/d­ev/­pep­s/p­ep-­0498/
       
 

Comments

No comments yet. Add yours below!

Add a Comment

Your Comment

Please enter your name.

    Please enter your email address

      Please enter your Comment.

          Related Cheat Sheets

          Python F-Strings Basics Cheat Sheet

          More Cheat Sheets by BrianAllan

          Python F-Strings Basics Cheat Sheet