A few examples that will save the day probably* 95% of time.
*I don’t have the actual data but seriously, I bet you’ll find those tips useful more often than not!
Introduction
This article was originally posted on Medium.
I use f-strings
every day. The irony is I also every day end up searching the Web to find the correct format to use. Until one day I thought a better use of my time would be to create a cheat sheet of the most common formatting cases — AKA this article. It covers the following:
- integers, floats, numbers and scientific notation
- percentages %
- dates
- padding
- adding +/- sign in front of a number
It’s important to note that the f-strings
were first introduced in Python 3.6 (PEP 498 if you REALLY must know) so make sure to check the Python version first, if things don’t work for you.
The format
The most basic f-string
format goes like this:
You can use this format to print numbers, texts, or even evaluate expressions.
author = "pawjast"
year = 2022
print(f"Example 1: {author}") # string
print(f"Example 2: {year}") # number
print(f"Example 3: {2 + 2}") # expression
The output:
Example 1: pawjast
Example 2: 2022
Example 3: 4
You might have noticed that the 2+2
expression in Example 3 got evaluated and 4
was printed.
You’ll get both, the name and the value if you add =
sign to a variable.
text = "Data Science Blog"
print(f"{text=}")
The output:
text='Data Science Blog'
Template below generalizes how you can add a specific format to a variable:
Next paragraphs shows examples of how to use it.
Recap on numbers
Last stop before going any further. I’ll be using different ways of writing numbers later in the article so let’s review the most common ones.
int_1 = 1
int_with_separator = 1_000 # `int` with 1,000 separator
float_1 = 1.125
float_2 = 3.50
scientific_1 = 1.23e2 # 1.23 * 10^2
print(f"Example 1 - int: {int_1}")
print(f"Example 2 - int with _ as thousands separator: {int_with_separator}")
print(f"Example 3 - float: {float_1}")
print(f"Example 4 - float with trailing zero: {float_2}")
print(f"Example 5 - float in scientific notation: {scientific_1}")
The output:
Example 1 - int: 1
Example 2 - int with _ as thousands separator: 1000
Example 3 - float: 1.125
Example 4 - float with trailing zero: 3.5
Example 5 - float in scientific notation: 123.0
You can observe that:
floats
had the trailing zeros truncated (Example 4)- scientific notation was printed as a regular
float
- the rest of the variables were printed “as is”
Floats
The float
type is enforced by using code f
. What you want to control in floats
is the number of decimal places.
pi_val = 3.141592
print(f"Example 1: {pi_val:f}")
print(f"Example 2: {pi_val:.0f}")
print(f"Example 3: {pi_val:.1f}")
print(f"Example 4: {pi_val:.3f}")
The output:
Example 1: 3.141592
Example 2: 3
Example 3: 3.1
Example 4: 3.142
💡 Side note: f-strings
are flexible enough to allow nesting.
float_val = 1.5
precision = 3
print(f"{float_val:.{precision}f}")
The output:
1.500
Percentage
Use code %
to enforce percentage type. Percentage is still a float
so you can still use .<whole_number>
to control the precision.
val = 0.5
print(f"Example 1: {val:%}")
print(f"Example 2: {val:.0%}")
The output:
Example 1: 50.000000%
Example 2: 50%
More examples of controlling precision in %
:
val = 1.255
print(f"Example 1: {val:.0%}")
print(f"Example 2: {val:.1%}")
The output:
Example 1: 125%
Example 2: 125.5%
Scientific notation
If you want scientific notation to be printed as such (and not as a regular float
) it can be enforced with e
or E
code.
val = 1.23e3 # 1.23 * 10^3
print(f"Example 1: {val:e}")
print(f"Example 2: {val:E}")
The output:
1: 1.230000e+03
2: 1.230000E+03
No surprise the precision can be controlled in this case too.
val = 1.2345e3
print(f"{val:.2e}")
The output:
1.23e+03
You can even print a regular number in scientific notation.
val = 2022
print(f"{val:.3e}")
The output:
2.022e+03
Integers
Integers
are enforced using code d
.
val = 1
print(f"{val:d}")
The output:
1
Adding ,
to the code will print the thousands separator.
int_1 = 1000
int_2 = 1000_000_000
print(f"{int_1:,d}")
print(f"{int_2:,d}")
The output:
1,000
1,000,000,000
Numbers
If the aim is to just print a number, you can use generic code — n
.
val_int = 1
val_float = 1.234
val_scient = 4.567e2
print(f"{val_int =: n}")
print(f"{val_float =: n}")
print(f"{val_scient =: n}")
The output:
val_int = 1
val_float = 1.234
val_scient = 456.7
You can still use .<whole_number>
format to control the precision.
💡 Side note: in this case whole_number
determines the total number of digits printed, not the number of decimal points! On top of that, n
code will decide the best output format for a number.
val_float_1 = 1.234
val_float_2 = 20.234
val_float_3 = 123.456
print(f"{val_float_1 =: .2n}") # prints as truncated float
print(f"{val_float_2 =: .2n}") # prints as int
print(f"{val_float_3 =: .2n}") # prints as scientific notation
The output:
val_float_1 = 1.2
val_float_2 = 20
val_float_3 = 1.2e+02
Dates
from datetime import date, datetime
Printing a date “as is” works exactly like printing any other variable.
day = date(
year=2022,
month=9,
day=1
)
print(f"{day}")
The output:
2022-09-01
To recreate the format you will use the following codes:
%Y
for year%m
for month%d
for day
With those codes you can e.g. create a new date format.
print(f"{day:%Y-%m-%d}") # default appearance
print(f"{day:%Y/%m/%d}") # use `/` as separator
The output:
2022-09-01
2022/09/01
It’s also possible to print a month as a text:
%b
— short version%B
— long version
print(f"{day:%Y %b %d}")
print(f"{day:%Y %B %d}")
The output:
2022 Sep 01
2022 September 01
The same variable can be printed multiple times.
print(f"{day:%b or %B}?")
print(f"{day:%Y %Y %Y}"
The output:
Sep or September?
2022 2022 2022
Reusing the same variable can be useful e.g. when you want to print the date and provide the day of the week as text (using code %A
).
print(f"{day:%Y %b %d (%A)}")
The outcome:
2022 Sep 01 (Thursday)
Last but not least, you can swap %Y
for %y
to get short version of the year.
print(f"{day:%y.%m.%d}")
The output:
22.09.01
Datetime
Let’s specify two datetime
variables.
day_and_time = datetime(
year=2022,
month=9,
day=1,
hour=17,
minute=30,
second=45
)
now = datetime.now()
print(f"{day_and_time}")
print(f"{now}") # with mircoseconds
The output:
2022-09-01 17:30:45
2022-12-08 15:49:37.810347
Time format requires the following codes:
%H
— hour%M
— minute%S
— second%f
— millisecond (1s = 1000 milliseconds)
Therefore, the default format would look like below.
print(f"{now:%Y-%m-%d %H:%M:%S.%f}")
The outcome:
2022-12-08 15:49:37.810347
f-string
obviously creates a string
(try this code to confirm it: type(f”now:%Y-%m-%d %H:%M%S.%f}”)
). Therefore, if e.g. you are not happy with the number of decimal points for milliseconds, you can easily truncate them.
print(f"{now:%Y-%m-%d %H:%M:%S.%f}"[:22])
The output:
2022-12-08 15:49:37.81
In order to change the 24hr format to 12hr format, you will need to:
- swap hour code from
%H
to%I
- Optionally add
%p
at the end if you want to add AM/PM to the time
print(f"24hr: {day_and_time:%Y-%m-%d %H:%M:%S}")
print(f"12hr: {day_and_time:%Y-%m-%d %I:%M:%S}")
print(f"12hr with AM/PM: {day_and_time:%Y-%m-%d %I:%M:%S %p}")
The output:
24hr: 2022-09-01 17:30:45
12hr: 2022-09-01 05:30:45
12hr with AM/PM: 2022-09-01 05:30:45 PM
Few more useful date formats:
%j
for day of the year%W
for week of the year (assuming Monday as first day of the week)%U
for week of the year (assuming Sunday as first day of the week
day = date(
year=2018,
month=9,
day=17
)
print(f"The date: {day}")
print(f"Day of the year: {day: %j}")
print(f"Week of the year (Mon): {day: %W}")
print(f"Week of the year (Sun): {day: %U}")
The outcome:
The date: 2018-09-17
Day of the year: 260
Week of the year (Mon): 38
Week of the year (Sun): 37
Padding
Padding with empty spaces.
val = 1
print(f"1: {val:1d}")
print(f"2: {val:2d}")
print(f"3: {val:3d}")
The output:
1: 1
2: 1
3: 1
Padding with zeros.
val = 1
print(f"1: {val:01d}")
print(f"2: {val:02d}")
print(f"3: {val:03d}")
The output:
1: 1
2: 01
3: 001
I usually use zero — padding with for
loop to keep the text nicely aligned in the terminal.
for i in range(11):
print(f"{i:02d}")
The output:
01
02
...
09
10
Positive/negative sign
In some cases you will require to show a +/-
sign next to a number.
positive = 1.23
negative = -1.23
print(f"1: {positive:+.2f} {negative:+.2f}")
print(f"2: {positive:-.2f} {negative:-.2f}")
print(f"3: {positive: .2f} {negative: .2f}")
The output:
1: +1.23 -1.23
2: 1.23 -1.23
3: 1.23 -1.23
Combining all things together
# print variable with name, limit precision and thousands separator
val = 11500.23456
print(f"{val = :,.3f}")
The output:
val = 11,500.235
We’re done 🎉.
Full code
Connect with me
💬 Medium ◽ Twitter / X ◽ GitHub ◽ Substack ◽ LinkedIn
Resources
1️⃣ https://docs.python.org/3/reference/lexical_analysis.html#f-strings
2️⃣ https://docs.python.org/3/library/string.html#format-specification-mini-language