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) |
|
|
> |
- |
|
|
, |
|
|
|
^ |
' ' |
|
|
|
|
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 |
_ |
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 |
|
|
Number. Same as d
, 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. x
vs X
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 |
f"binary: {i:b}; octal: {i:o}; hex: {i:x} or {i:X}"
|
|
'binary: 1101; octal: 15; hex: d or D' |
# the #-option adds prefixes |
f"binary: {i:#b}; octal: {i:#o}; hex: {i:#x} or {i:#X}"
|
|
'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 |
print(''.join([f"{x:c}" for x in range(33,42)]))
|
|
!"#$%&'() |
# 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 |
import locale
locale.setlocale(locale.LC_ALL, '')
|
# then use format type 'n' |
|
'1,000,000' |
|
|
Float Presentation Types
Type |
Name |
For a given precision p ... |
|
Scientific Notation |
The coefficient has 1 digit before and p
digits after the decimal point. |
|
Fixed-Point Notation |
There are p
digits following the decimal point. |
|
General Format |
Rounds number to p
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 |
f"{1000:.1e} vs {1000:.1E}"
|
'1.0e+03 vs 1.0E+03' |
# Lower case f versus upper case F |
f"{1000:.1f} vs {1000:.1F}"
|
'1000.0 vs 1000.0' |
# Lower case g versus upper case G |
f"{1000:.1g} vs {1000:.1G}"
|
'1e+03 vs 1E+03' |
# Lower versus upper case NaN representation |
nan = float('nan') f"{nan:f} vs {nan:F}"
|
'nan vs NAN'
|
General Format (g or G) Rule
Given the number y
and the precision specification p
: |
(a) Let exp
= the exponent of y
in scientific notation. |
|
"Yes": Format y
using fixed-point notation and a new precision: p' = p - (1 + exp)
where p
represents the number of significant 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 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 y
using scientific notation and a new precision: p' = p - 1
where p
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 = 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 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 |
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 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 |
|
= e
or f
( E
or F
) according to the General Format Rule |
none |
|
|
|
|
|
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. |
|
|
|
|
Uses the current locale setting for separator formatting. |
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 9000000.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"{si:#n} {li:#n} {sf:#n} {lf:#n} {sc:#n}"
|
'55 666666 7.77777 8888.88 9.00000e+06' |
# n with precision = 3 (precision not allowed for integers) f"{si:.3n} {li:.3n} {sf:.3n} {lf:.3n} {sc:.3n}"
|
|
# e with precision = 3 (forces 3 digits after decimal point) f"{si:.3e} {li:.3e} {sf:.3e} {lf:.3e} {sc:.3e}"
|
# including the #-option gives the same result here f"{si:#.3e} {li:#.3e} {sf:#.3e} {lf:#.3e} {sc:#.3e}"
|
'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) f"{si:.3f} {li:.3f} {sf:.3f} {lf:.3f} {sc:.3f}"
|
# including the #-option gives the same result here f"{si:#.3f} {li:#.3f} {sf:#.3f} {lf:#.3f} {sc:#.3f}"
|
'55.000 666666.000 7.778 8888.880 9000000.000' |
# g with precision = 3 (shows no unnecesary zeros or decimal points) f"{si:.3g} {li:.3g} {sf:.3g} {lf:.3g} {sc:.3g}"
|
'55 6.67e+05 7.78 8.89e+03 9e+06' |
# g with #-option (forces showing 3 significant digits) f"{si:#.3g} {li:#.3g} {sf:#.3g} {lf:#.3g} {sc:#.3g}"
|
'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 f"{10:#.0e} {10:#.0f} {10:#.0g}"
|
'1.e+01 10. 1.e+01' |
|
Created By
Metadata
Comments
No comments yet. Add yours below!
Add a Comment
Related Cheat Sheets
More Cheat Sheets by BrianAllan