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) replacement fields containing Python expressions 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 replacement field:
f"{replacement_field}"
Replacement Field
{f-expression = !conversion:format_specifier}
A replacement field is signaled by a pair of curly braces:
{ }
A replacement field consists of a Python expression for evaluation with optional debugging mode (=), type conversion (!), and format specification (:).
Substituting into the f-string template:
f" text {f-expression = !conversion:format_specifier} text ..."
Format Specifier
:fill align sign # 0 width sep .precision type
Brief Summary of the Format Specification Mini-Language
fill
: the padding character
align
: alignment of text within the space
sign
: how + and - are used preceding numbers
#
: alternate presentation format for some number types
0
: sign-aware, zero-padding 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 presentation to use based on data type
Note:
sign
,
#
,
0
,
sep
,
precision
, and
type
are of particular interest for number formatting, the focus of this cheatsheet. For a general treatment of F-Strings, see my cheatsheet Python F-Strings Basics.
Format Specifier: Options
fill | align | sign | # | width | sep | .prec | type |
char | < | + | digit(s) | _ | digit(s) | string:
| |
> | - | , | number:
| ||||
^ | ' ' | integer:
,
,
,
,
,
| |||||
= | float:
,
,
,
,
,
,
|
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 |
_ | underscore. 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 | |
| '+3 or -3' |
# sign (-): a sign is only used for negative numbers | |
| '3 or -3' |
# no sign is the same as sign (-) | |
| '3 or -3' |
# sign (space): a leading space for positive numbers and a minus sign for negative | |
| ' 3 or -3' |
# sign (+), separator (,) | |
| '+10,000' |
# fill (?), align (<), sign (+), width (11), sep (,) | |
| '+10,000????' |
Sign Aware Padding
Using the = alignment option forces the padding determined by the fill and width specifications to be placed after the sign (if any) but before the digits. This is useful for number representations like '+000042'. This alignment option is only available for numeric types. | |
The 0-option produces sign aware zero-padding just like the = alignment option with a fill of '0'. It is produced by preceding the field width specification with '0'. | |
# fill (?), align (=), sign (+), width (5) | |
| '+???3' |
# fill (0), align (=), sign (+), width (5) | |
| '+0003' |
# sign (+), 0-option, width (5) | |
| '+0003' |
# 0-option, width (5) | |
| '00003' |
Integer Presentation Types
Decimal Integer Types | |||
| Decimal Integer: the number in base 10 | ||
None | Same as
| ||
| Number. Same as
, except uses current locale setting for the appropriate number separator character | ||
Others | |||
| Binary: the number in base 2. | ||
| Octal: the number in base 8. | ||
,
| Hex: the number in base 16.
vs
signals lower vs upper case for digits > 9 | ||
| Unicode Character. Converts decimal integer to the corresponding 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
| |
# representing decimal 13 in binary, octal, and hexadecimal | |
| |
'binary: 1101; octal: 15; hex: d or D' | |
# the #-option adds prefixes | |
| |
'binary: 0b1101; octal: 0o15; hex: 0xd or 0XD' | |
# binary with zero padding | |
| '00001101' |
# binary with prefix and zero padding | |
| '0b001101' |
# fill (0), align (=), #-option, width (8), type (b) | |
| |
'0b001101' | |
# returns the unicode character with decimal representation 36 | |
| '$' |
# printing symbols with unicode decimal representations 33-41 | |
| |
!"#$%&'() | |
# separator (,) and type (d) | |
| '10,000' |
# type d is the default for integers, so unnecessary | |
| '10,000' |
# separator (_), type (b) | |
| '100_1011_0000' |
# to use locale specific number formatting, set the locale | |
| |
# then use format type 'n' | |
| '1,000,000' |
Float Presentation Types
Type | Name | For a given precision |
,
| Scientific Notation | The coefficient has 1 digit before and
digits after the decimal point. |
,
| Fixed-Point Notation | There are
digits following the decimal point. |
,
| General Format | Rounds number to
significant 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 decimal.Decimal is p large enough to show all coefficient 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 Comparisons
# %-style with precision=1 | |
| '50.0%' |
# Lower case e versus upper case E | |
| '1.0e+03 vs 1.0E+03' |
# Lower case f versus upper case F | |
| '1000.0 vs 1000.0' |
# Lower case g versus upper case G | |
| '1e+03 vs 1E+03' |
# Lower versus upper case NaN representation | |
| 'nan vs NAN' |
General Format (g or G) Rule
Given the number
and the precision specification
: |
(a) Let
= the exponent of
in scientific notation. |
(b) Is
? |
"Yes": Format
using fixed-point notation and a new precision:
where
represents the number of significant digits before any trailing zeros are removed. (In fixed-point format, the precision, here
, determines the number of digits following the decimal point. When it is positive, the value
can be interpreted as the total number of digits before the decimal; otherwise, it represents the total number of zeros after the decimal point but before the significant digits.) |
"No": Format
using scientific notation and a new precision:
where
represents the total number of significant digits in the coefficient before any trailing zeros are removed. (In scientific format, the precision determines the number of digits displayed after the decimal point of the coefficient. So, the total number of digits displayed will be: precision + 1 =
.) |
(c) With the #-option (
,
): Keep any trailing zeros and the decimal point.
,
): If the result has insignificant trailing zeros, remove them as well as an unflanked decimal point. |
Note: In both cases in (b), the original precision specification
p
determines the effective number of significant digits up until insignificant trailing zeros are removed in (c).
General Format (g or G): Illustration
#.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 | f | |
10.00 | 10 | 1 | f |
100.0 | 100 | 2 | f |
1000. | 1000 | 3 | f |
1.000e+04 | 1e+04 | 4 | e |
In this illustration, the precision specification is
p = 4
; so, for
exp
from -4 to 3, fixed-point notation (
f
) is used; otherwise, scientific notation (
e
) is used.
Types with Conditional Formatting
Type | Interpretation | |
,
| =
or
(
or
) according to the General Format Rule | |
none | =
for strings | |
=
for integers | ||
=
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 faithfully. | |
| =
for integers | |
=
for floats | Uses the current locale setting for separator formatting. |
Examples: Both Integers and Floats
# small integer
# large integer
# small float
# large float
# scientific notation |
# none -- no type specified
|
'55 666666 7.77777 8888.88 9000000.0' |
# n -- number type
|
'55 666666 7.77777 8888.88 9e+06' |
# n with #-option
|
'55 666666 7.77777 8888.88 9.00000e+06' |
# n with precision = 3 (precision not allowed for integers)
|
|
# e with precision = 3 (forces 3 digits after decimal point)
|
# including the #-option gives the same result here
|
'5.500e+01 6.667e+05 7.778e+00 8.889e+03 9.000e+06' |
# f with precision = 3 (forces 3 digits after decimal point)
|
# including the #-option gives the same result here
|
'55.000 666666.000 7.778 8888.880 9000000.000' |
# g with precision = 3 (shows no unnecesary zeros or decimal points)
|
'55 6.67e+05 7.78 8.89e+03 9e+06' |
# g with #-option (forces showing 3 significant digits)
|
'55.0 6.67e+05 7.78 8.89e+03 9.00e+06' |
# In float types generally, the #-option forces a decimal point occurrence even when no digits follow it
|
'1.e+01 10. 1.e+01' |
References
"A Guide to the Newer Python String Format Techniques" by John Sturtz at Real Python: https://realpython.com/python-formatted-output/#the-python-formatted-string-literal-f-string |
"Python 3's f-Strings: An Improved String Formatting Syntax (Guide)" by Joanna Jablonski at Real Python: https://realpython.com/python-f-strings/ |
"Format String Syntax" including "Format Specification Mini-Language" from the page "
-- Common string operations": https://docs.python.org/3/library/string.html#format-string-syntax |
"2.4.3. Formatted string literals" from the page "2. Lexical analysis": https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals |
"PEP 498 -- Literal String Interpolation": https://www.python.org/dev/peps/pep-0498/ |
"Python String Format Cookbook": https://mkaz.blog/code/python-string-format-cookbook/ |