Python 3's f-strings

mylesb.ca | me@mylesb.ca | @mylesb

f-strings are TOTALLY AWESOME!

In [1]:
group = 'Python Toronto'

f'Hello {group}!'
Out[1]:
'Hello Python Toronto!'

They also support expressions inside the { }

In [2]:
f'Hello {group.upper()}!'
Out[2]:
'Hello PYTHON TORONTO!'

Even dict

In [3]:
portfolio = {'AAPL': 222.77, 'RHT': 122.31, 'GOOGL': 1111.77}
In [4]:
f'${portfolio['GOOGL']}USD'
  File "<ipython-input-4-552a7f3505aa>", line 1
    f'${portfolio['GOOGL']}USD'
                       ^
SyntaxError: invalid syntax

While that's a little confusing...

In [5]:
f"${portfolio['GOOGL']}USD"
Out[5]:
'$1111.77USD'

But look what else you can do...

In [6]:
f"${portfolio['GOOGL']:,}USD"
Out[6]:
'$1,111.77USD'

You can use them in class...

In [7]:
class Drink:
    def __init__(self, name, caffine):
        self.name = name
        self.caffine = caffine

    def __str__(self):
        return f'{self.name}'

    def caffine_for_quantity(self, size=100000):
        return (
            f'{self.name} has {self.caffine*size:.0f} '
            f'mg for {size/1000:.0f} grams.'
        )
In [8]:
coffee = Drink('Coffee', .0004)

f'{coffee.caffine_for_quantity()}'
Out[8]:
'Coffee has 40 mg for 100 grams.'
In [9]:
f'{coffee.caffine_for_quantity(459732)}'
Out[9]:
'Coffee has 184 mg for 460 grams.'
In [10]:
import timeit

format_funcs = {
    'f-strings': """
def format(superhero, rank):
    return f'{superhero} has a rank of {rank}!'
""",
    '%-formatting': """
def format(superhero, rank):
    return '%s has a rank of %s!' % (superhero, str(rank))
""",
    '.format()': """
def format(superhero, rank):
    return '{} has a rank of {}!'.format(superhero, str(rank))
""",
    'concatenation +': """
def format(superhero, rank):
    return superhero + ' has a rank of ' + str(rank) + '!'
""",
    'concatenation ()': """
def format(superhero, rank):
    return superhero, ' has a rank of ', str(rank), '!'
"""
}

test_func = """def test_format():
    for superhero in ('Wonder Woman', 'Supergirl', 'Batman', 'Robin'):
        for rank in range (1, 101):
            format(superhero, rank)
"""

for key, func in format_funcs.items():
    print(key, timeit.timeit('test_format()', func + test_func, number=10000))
f-strings 1.2643750110000003
%-formatting 2.3980831910000013
.format() 3.153147552
concatenation + 2.0541713359999996
concatenation () 1.5040422759999998
In [11]:
%matplotlib inline
import pandas as pd

df = pd.DataFrame([
    {'method': 'f-strings', 'time': 1.2444629460001124},
    {'method': '%-formatting', 'time': 2.323644578999847},
    {'method': '.format()', 'time': 3.0558486750001066},
    {'method': 'concatenation +', 'time': 2.0393622280003},
    {'method': 'concatenation ()', 'time': 1.4142364679996717}
])

and it's fast...

In [12]:
df.sort_values('time').plot(kind='barh', x='method', y='time')
Out[12]:
<matplotlib.axes._subplots.AxesSubplot at 0x1120995f8>

Want to work with me?

GrantMatch is looking for a Student Co-op -- Junior Software Developer

https://fairtax.ca/careers/junior-software-developer/

Thx for you time!

Myles Braithwaite