Learn Python Series (#27) - Handling Strings Part 3 (F-Strings)

in #utopian-io6 years ago

Learn Python Series (#27) - Handling Strings Part 3 (F-Strings)

python_logo.png

Repository

https://github.com/python/cpython

What will I learn?

  • In this episode of the Learn Python Series we will introduce F-Strings, also called "Formatted String Literals", as a new way (introduced in Python 3.6) to format strings,
  • a small re-cap is given, in which we'll quickly go over the handling of strings that was covered in in Learn Python Series (#2) - Handling Strings Part 1 and Learn Python Series (#3) - Handling Strings Part 2,
  • that re-cap is needed to explain how F-Strings are both easier to read and write, less verbose, more powerful than operator overloaded %-formatting and the str.format() mechanisms,
  • regarding F-Strings you will learn about (basic) string-only substitutions, mixed datatype substitutions, substituting dictionary elements, how to evaluate expressions, functions and methods right inside an F-String's placeholder, about formatting dates and times, multiline formatting, and about some neat format specifiers.

Requirements

  • A working modern computer running macOS, Windows or Ubuntu;
  • An installed Python 3(.6) distribution, such as (for example) the Anaconda Distribution;
  • The ambition to learn Python programming.

Difficulty

  • Beginner

Curriculum (of the Learn Python Series):

Additional sample code files

The full - and working! - iPython tutorial sample code file is included for you to download and run for yourself right here:
https://github.com/realScipio/learn-python-series/blob/master/strings-tut03.ipynb

GitHub Account

https://github.com/realScipio

Learn Python Series (#27) - Handling Strings Part 3 (F-Strings)

Right at the beginning of the Learn Python Series we already covered a lot regarding the handling of strings in Learn Python Series (#2) - Handling Strings Part 1 and Learn Python Series (#3) - Handling Strings Part 2.

What we did not discuss yet in those two earlier episodes, is that beginning with Python 3.6 a new way to perform string substitution has been introduced: the "Formatted String Literals", also dubbed "F-Strings" for short. Let's dive right in!

A small re-cap on Output Formatting

Basic printing

Say we have one string variable and we'd like to print it, then of course we can do so like this:

str1 = 'This is a sentence'
print(str1)
This is a sentence

String concatenation

If we want to "glue together" multiple strings to form a larger string, then string concatenation using the + operator also works straightforward:

str2 = 'How do you like '
str3 = 'your eggs in '
str4 = 'the morning?'
sentence = str2 + str3 + str4
print(sentence)
How do you like your eggs in the morning?

Explicit type conversion when concatenating mixed data types

Basic string concatenation doesn't work when you try to concatenate one or more string variables to other data types, for example an integer. Prior to concatenating those non-string variables, you'd first need to explicitly convert their data type to a string:

magic_number = 3
str5 = " is the magic number"
sentence = str(magic_number) + str5
print(sentence)
3 is the magic number

Operator overloaded %-formatting

Borrowed from C/C++, you can use the % operator together with placeholders to format strings. To substitute multiple variables, use a tuple. For example:

animal = 'dog'
human = 'man'
sentence = "A %s is a %s's best friend" % (animal, human)
print(sentence)
A dog is a man's best friend

I personally think this is not so easily readable, it gets a bit "messy", don't you agree?

The format() string method

Introduced in Python 2.6, str.format() can be considered an improvement to %-formatting, and uses normal function call syntax in conjunction with a format string / template. Like so:

Empty placeholders:

name = 'scipio'
rep = 63
sentence = "My name is {} and my current Steem reputation is {}".format(name, rep)
print(sentence)
My name is scipio and my current Steem reputation is 63

Indexed placeholders:

cur1 = 'SBD'
cur2 = 'Steem'
sentence1 = "I like {0} better than {1}".format(cur1, cur2)
sentence2 = "I like {1} better than {0}".format(cur1, cur2)
print(sentence1)
print(sentence2)
I like SBD better than Steem
I like Steem better than SBD

Dictionary keys:

dict = {'ch1': 'a', 'ch2': 'b', 'ch3': 'c'}
sentence = "{ch1}, {ch2}, {ch3}".format(**dict)
print(sentence)
a, b, c

Keyword arguments:

ch1 = 'a'
ch2 = 'b'
ch3 = 'c'
sentence = "{ch1}, {ch2}, {ch3}".format(ch1=ch1, ch2=ch2, ch3=ch3)
print(sentence)
a, b, c

The str.format() format is, in my opinion, easier to read than %-formatting, but can still get pretty verbose and lengthy if you're handling lots of parameters and / or long format strings.

Formatted String Literals, "F-Strings"

Enter F-strings, introduced in Python 3.6. F-strings begin with an f and, like the str.format() method use {} curly braces containing variable names / expressions that will be substituted with the resulting values, at runtime. The F-strings syntax looks a lot like str.format() but is much less verbose and therefore much easier on the eyes! Let's have a look:

String-only substitutions:

In its most basic form, this is how you use F-Strings:

  • the string variable named sentence is prepended with the letter f
  • and to "inject" the two other strings named animal and human inside it, simply place the placeholders surrounded by curly braces {} and inside it contain the variable names.
animal = 'dog'
human = 'man'
sentence = f"A {animal} is a {human}'s best friend"
print(sentence)
A dog is a man's best friend

As you can tell right away, F-Strings are very easy to read/write and understand!

Mixed datatype substitutions:

As opposed to basic string concatenation, F-Strings allow for substituting various and mixed data types, such as, in this example, a string steem and a float steem_price:

steem = 'Steem'
steem_price = 1.52

sentence = f"The price of {steem} is ${steem_price}"
print(sentence)
The price of Steem is $1.52

Dictionary keys:

In case you want to use a dictionary, the F-String format becomes slightly more verbose, where you reference the dictionary object together with its key, which will be substituted with the corresponding value, like so:

dict = {
    "emotion": "joy",
    "response": "smiling"
}
sentence = f"The woman began {dict['response']} when she felt {dict['emotion']}"
print(sentence)
The woman began smiling when she felt joy

Expression evaluation:

A very cool feature of F-Strings is that you are allowed to directly insert expressions, that will be evaluated (to its corresponding value) at runtime. The following example, calculating and printing the ratio of Steem and SBD prices, shows this perfectly:

steem = 'Steem'
steem_price = 1.52
sbd = 'SBD'
sbd_price = 1.40

sentence = f"You can now buy {sbd_price / steem_price} {steem} for 1 {sbd}"
print(sentence)
You can now buy 0.9210526315789473 Steem for 1 SBD

Function calling:

What's even cooler is that you can even call (self-defined) functions with passed-in arguments, like so:

from math import pi

def circle_area(radius):
    return pi * radius ** 2

radius = 3
sentence = f"The area of a circle with radius {radius} is {circle_area(radius)}"
print(sentence)
The area of a circle with radius 3 is 28.274333882308138

Method calling:

And the same goes for built-in methods: in the following example, since name is a string, you can use the str.upper() method (for example) to print capitals:

name = 'scipio'
sentence = f"My name is {name.upper()}"
print(sentence)
My name is SCIPIO

Multiline F-Strings:

Longer F-Strings can be broken down into smaller chunks in a multiline-style. Make sure to surround the total F-String with parentheses () and to prepend each substring with the f on each line, like so:

name = 'scipio'
hobby = 'programming'
language = 'Python'

sentence = (
    f"My name is {name}, "
    f"and as a hobby I like "
    f"{hobby} in {language}"
)
print(sentence)
My name is scipio, and as a hobby I like programming in Python

Format specifiers:

If you don't specify the precision, a float such as PI will get printed with a lot (15) of digits, like so:

from math import pi

sentence = f"PI is equal to {pi}"
print(sentence)
PI is equal to 3.141592653589793

However, F-Strings allow for "format specifiers" that enable you to precisely define the precision you want printed.

In order to do so, use the format

f"{value:{width}.{precision}type_specifier}"

E.g.:

from math import pi

sentence = f"PI is equal to {pi:20.4f}"
print(sentence)
PI is equal to               3.1416

or

from math import pi

width = 20
precision = 4

sentence = f"PI is equal to {pi:{width}.{precision}f}"
print(sentence)
PI is equal to               3.1416

Nota bene: The precision argument doesn't just truncate but correctly round PI.

In case you want to zero pad all numbers ranging from 1 to 10, then width=4, "aligned right" is done like so:

for i in range(1,11):
    print(f"{i:0>4}")
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010

You could for example also use another padding character, such as * and align the numbers left, like this:

for i in range(1,11):
    print(f"{i:*<4}")
1***
2***
3***
4***
5***
6***
7***
8***
9***
10**

Date formatting

In the Learn Python Series episodes 22 and 23 we already discussed (among other things of course) how to format dates and times. Almost the exact same techniques can be used on F-Strings as well.

Without any formatting, F-String printing of a date looks like this:

from datetime import datetime

birthday = datetime(1988,6,25)
print(f"{birthday}")
1988-06-25 00:00:00

The same common directives as discussed in episodes 22 and 23, also work with F-Strings:

  • %a: abbreviated weekday name
  • %A: full weekday name
  • %b: abbreviated month name
  • %B: full month name
  • %c: date/time representation of the current locale (e.g. Sun Apr 29 22:15:37 2018)
  • %d: day of the month (01 .. 31)
  • %H: 24-hour clock hour (00 ..23)
  • %j: day of the year (001 .. 366)
  • %m: month (01 ..12)
  • %M: minute (00 ..59)
  • %S: seconds
  • %w: weekday (0 .. 6)
  • %W: week number (00 .. 53)
  • %Y: 4-digit year
  • %Z: Timezone name

So, in order to print Saturday, June 25, 1988 we simply place the format directives we want to use inside the placeholder, after the variable name and the colon :

from datetime import datetime

birthday = datetime(1988,6,25)
print(f"{birthday:%A, %B %d, %Y}")
Saturday, June 25, 1988

What did we learn, hopefully?

This Part 3 episode of my "Handling Strings" subseries shortly re-capped on what was discussed about string formatting in parts 1 and 2, and then introduced how to use F-Strings. We learned that not only are F-Strings "easy on the eyes", but that they're also pretty powerful to use, as you can directly insert expressions, call functions, apply methods, which all evaluate at runtime.

I hope you will enjoy using F-Strings over other string formatting techniques as much as I do!
See you in the next episode!

Thank you for your time!

Sort:  

Thank you, scipio. Upvoted and resteemed!

@ArtTurtle is an upvote bot run by @Artopium dedicated to upvoting your art, music, fashion, video and books. Find out how you can get an upvote for every creative post you make by visitng @ArtTurtle and reading the latest report.

Thx! I think your @artturtle project is sympathetic! Keep it up!

Thank you for your contribution.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Hey @scipio
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!