Python Book
πŸ‡ΊπŸ‡¦ Stand with UkraineπŸŽ“Training Suite
  • Book overview
  • Notes about this book
  • 1. Introduction to Python
    • What is Python
    • Basic syntax
    • Objects in Python
    • Python overview
    • Installation, IDEs etc.
    • ipython
    • Sources for self-learning
  • 2. Strings and numbers
    • Getting help
    • Introspection
    • Basic types
    • None object
    • Numbers
    • Strings
    • Unicode
    • String Formatting
    • Regular expressions
    • Sources for self-learning
  • 3. Containers
    • Data Structures
    • Lists
    • Tuples
    • Dictionaries
    • Sets
    • Conditions
    • Loops
    • Additional modules
    • Sources for self-learning
  • 4. Functions
    • Functions
    • Scopes of visibility
    • Generators
    • Lambdas
    • Type hints
    • Function internals
    • Sources for self-learning
  • 5. Functional Programming
    • Builtins
    • Iterable
    • Iterator
    • Functional Programming
    • Functools
    • Comprehensions
    • Additional modules
    • Sources for self-learning
  • 6. Code Styling
    • Zen of Python
    • Lint
    • PEP 8
    • Modules
    • Packages
    • Sources for self-learning
  • 7. OOP
    • OOP Basics
    • Code design principles
    • Classes
    • Method Resolution Order
    • Magic attributes and methods
    • Super
    • Sources for self-learning
  • 8. Decorators, Exceptions
    • Decorators
    • Exceptions
    • Sources for self-learning
  • 9. Testing
    • Basic Terminology
    • Testing theory
    • Dev unit testing vs QA automated testing
    • Best Practices
    • Doctest
    • Unittest
    • Test Runners
    • Pytest
    • Nose
    • Continuous Integration
  • 10. System Libs
    • Working with files
    • System libraries
    • Subprocess
    • Additional CLI libraries
Powered by GitBook
On this page

Was this helpful?

Edit on Git
  1. 2. Strings and numbers

String Formatting

Formatting

There are two (old one new) styles of string formatting in Python. They are very similar when dealing with simple stuff but also have a lot of in-deep presentation and text transformation options

  1. printf-style (%, old) - based on C printf style formatting that handles a narrower range of types and is slightly harder to use correctly, but is often faster for the cases it can handle.

  2. str.format() (new) provides a large degree of flexibility and customization.

  3. f-strings (Python 3.6) - inline formatting allowing to insert variables by names with format similar to format()

πŸͺ„ Code:

print_me = 100500.12
print(  "1. %s" % print_me )         # Old format, %
print(  "2. {}".format(print_me) )   # New format, format()
print( f"3. {print_me}" )            # f-strings

πŸ“Ÿ Output:

1. 100500.12
2. 100500.12
3. 100500.12

% (printf-style formatting)

format % values

format is a string, % conversion specifications in format are replaced with zero or more elements of values.

A conversion specifier contains two or more characters and has the following components, which must occur in this order:

1. The '%' character - the start of the specifier.

2. Mapping key (optional), key name in parentheses (for example: (somename)).

3. Conversion flags (optional), which affect the result of some conversion types.

4. Minimum field width (optional). If specified as an '*' (asterisk), the actual width is read from the next element of the tuple in values, and the object to convert comes after the minimum field width and optional precision.

5. Precision (optional), given as a '.' (dot) followed by the precision. If specified as '*' (an asterisk), the actual precision is read from the next element of the tuple in values, and the value to convert comes after the precision.

6. Length modifier (optional).

7. Conversion type.

πŸͺ„ Code:

food = "Ceasar salad"
print("For breakfast today is %s" % food)

πŸ“Ÿ Output:

For breakfast today is Ceasar salad

πŸͺ„ Code:

food = "Pizza Pepperoni and burger"
money = 130.23
print( "For lunch we have: %35s, budget: %012.3f UAH" % (food, money) )

πŸ“Ÿ Output:

For lunch we have:          Pizza Pepperoni and burger, budget: 00000130.230 UAH

πŸͺ„ Code:

data = {"food": "Pasta Carbonara", "money": 300}
print( "And for dinner:  %(food)20s, money to spend: %(money)9.2f UAH" % data )

πŸ“Ÿ Output:

And for dinner:       Pasta Carbonara, money to spend:    300.00 UAH

{} / format()

It's better to use this for something that requries more complex formatting

Format strings contain β€œreplacement fields” surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a brace character in the literal text, it can be escaped by doubling: {{ and }}.

πŸͺ„ Code:

print("Our food today is {}".format(food))

πŸ“Ÿ Output:

Our food today is Pizza Pepperoni and burger

Several arguments:

πŸͺ„ Code:

print("Food: '{}', money: {} UAH".format(food, money))

πŸ“Ÿ Output:

Food: 'Pizza Pepperoni and burger', money: 130.23 UAH

It is possible when using new format (format()) to specify positions:

πŸͺ„ Code:

print("Food is {1}, money: {0}, (I have exactly ${0} in my wallet!)".format(money, food))

πŸ“Ÿ Output:

Food is Pizza Pepperoni and burger, money: 130.23, (I have exactly $130.23 in my wallet!)

It is possible to pass arguments by names:

data = {"money": 45, "food":"salad"}
# `**` - means we are passing dict as a sequence of key-value pairs
print("Want {food} but ${money} to spend".format(**data))
# print("Want {food} but ${money} to spend".format(money=45, food="salad"))

πŸ“Ÿ Output:

Want salad but $45 to spend

More examples:

πŸͺ„ Code:

"First thing in the morning is {0}".format("coffee") # References first positional argument

πŸ“Ÿ Output:

'First thing in the morning is coffee'

πŸͺ„ Code:

"I'd like a {} with coffee".format("cookie") # Implicitly references the first positional argument

πŸ“Ÿ Output:

"I'd like a cookie with coffee"

πŸͺ„ Code:

"Bring me {} and {}".format("coffee", "cookie") # Same as "From {0} to {1}"

πŸ“Ÿ Output:

'Bring me coffee and cookie'

πŸͺ„ Code:

"Remember my name: {name}".format(name="Heisenberg") # References keyword argument 'name'

πŸ“Ÿ Output:

'Remember my name: Heisenberg'

πŸͺ„ Code:

data = dict(do_what="Remember", my_what="name", name="Heisenberg")
"{do_what} my {my_what}: {name}".format(**data)

πŸ“Ÿ Output:

'Remember my name: Heisenberg'

πŸͺ„ Code:

"String has this method: {0.isalpha}".format("")  # 'isalpha' attribute of first positional arg

πŸ“Ÿ Output:

'String has this method: <built-in method isalpha of str object at 0x7efc5848c030>'

Differences between formatters:

%
{}
Output

'%s %s' % ('one', 'two')

'{} {}'.format('one', 'two')

one two

'%d %d' % (1, 2)

'{} {}'.format(1, 2)

1 2

---

'{1} {0}'.format('one', 'two')

two one

'%10s' % ('test',)

'{:>10}'.format('test')

test

'%-10s' % ('test',)

'{:10}'.format('test')

test

---

'{:_<10}'.format('test')

test______

---

'{:^10}'.format('test')

test

%
{}
Output

'%.3s' % ('abcdef',)

'{:.3}'.format('abcdef')

abc

'%d' % (42,)

'{:d}'.format(42)

42

'%06.2f' % (3.141592,)

'{:06.2f}'.format(3.14159)

003.14

---

'{p.type}'.format(p=Plant())

tree

In last example assuming p is the instance of Plant class defined like:

class Plant(object):
    type = 'tree

.format() cheatsheet

Data
Format
Output
Decription

123

{:10}

123

placeholder is 10

3.1415926

{:.2f}

3.14

2 decimal places

3.1415926

{:+.2f}

+3.14

2 decimal places with sign

2.71828

{:.0f}

3

No decimal places

1000000

{:,}

1,000,000

Number with comma sep

13

{:>10d}

13

Right aligned

13

{:<10d}

13

Left aligned

13

{:^10d}

13

Center aligned

.format() "cheats"

  • Show the same string several times

πŸͺ„ Code:

print('''{0}!
{1}. 
"{0}!" 
{1}. 
"What's gone with that boy, I wonder? You {0}!" {1}. 
'''.format('TOM', 'No answer'))

πŸ“Ÿ Output:

TOM!
No answer. 
"TOM!" 
No answer. 
"What's gone with that boy, I wonder? You TOM!" No answer.
  • Convert Values to different Bases

    • You can use the following letters to convert a number to their bases:

      • decimal, hex, octal, binary

πŸͺ„ Code:

print ("{0:d} - {0:x} - {0:o} - {0:b}".format(21))

πŸ“Ÿ Output:

21 - 15 - 25 - 10101
  • Escaping braces:

πŸͺ„ Code:

print ( "{{0}} / {}".format("TEST") )

πŸ“Ÿ Output:

{0} / TEST

f-strings formatting

New feature appeared in Python 3.6. It is possible to inject local variable right into string (variable interpolation)

Formatted string literals are prefixed with 'f' and are similar to the format strings accepted by str.format(). They contain replacement fields surrounded by curly braces. The replacement fields are expressions, which are evaluated at run time, and then formatted using the format() protocol

The format is:

f'<text> { <expression> <optional !s, !r, or !a> <optional : format specifier> } <text> ... '

πŸͺ„ Code:

var = 34.125
print(f'{var}')
print(f'{var:012.3f}')
print(f'{var:_^12.3f}')
print(f'{var:^10}')

πŸ“Ÿ Output:

34.125
00000034.125
___34.125___
  34.125

In case interpolating var is not defined - you'll get regular NameError:

πŸͺ„ Code:

f'{unexistent_var}'

πŸ“Ÿ Output:

---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

Input In [372], in <cell line: 1>()
----> 1 f'{unexistent_var}'


NameError: name 'unexistent_var' is not defined

πŸͺ„ Code:

f'{1/0}'

πŸ“Ÿ Output:

---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

Input In [373], in <cell line: 1>()
----> 1 f'{1/0}'


ZeroDivisionError: division by zero

f-string are evaluated only during creation (once):

πŸͺ„ Code:

value = 100500
str_ = f'Value is {value}'

print(str_)

πŸ“Ÿ Output:

Value is 100500

πŸͺ„ Code:

value = 42
print(str_)

πŸ“Ÿ Output:

Value is 100500

Expressions may be evaluated directly inside a string:

πŸͺ„ Code:

f'{ 1 + 2 }'

πŸ“Ÿ Output:

'3'

πŸͺ„ Code:

f'{"just another string"}'
'quoted string'

πŸ“Ÿ Output:

'quoted string'

πŸͺ„ Code:

d = {"a": 100500}
l = [1, 2, 3, 4, 5]

f'{d["a"], l[2:5]}'

πŸ“Ÿ Output:

'(100500, [3, 4, 5])'

πŸͺ„ Code:

def foo(x): 
    return "Hello! %s" % x
print(f'Result of function is:\n{foo("John")}')

πŸ“Ÿ Output:

Result of function is:
Hello! John

Format int value as hex:

πŸͺ„ Code:

value = 1234
f'input={value:#x}'

πŸ“Ÿ Output:

'input=0x4d2'

πŸͺ„ Code:

import datetime
now = datetime.datetime.now()
print(now.strftime("%a %d/%m/%Y"))
print(f'It was: {now:%a %d/%m/%Y}')

πŸ“Ÿ Output:

Wed 31/08/2022
It was: Wed 31/08/2022

Dynamic width

πŸͺ„ Code:

import decimal

width = 12
precision = 5
value = decimal.Decimal('12.34567')
f'result: {value:{width}.{precision}f}'

πŸ“Ÿ Output:

'result:     12.34567'

Templates

A bit underrated feature of builtin string module. Template is very simple template engine.

πŸͺ„ Code:

from string import Template 
s = Template('$who likes $what')
print(s.substitute(who='Johnny', what='whiskey'))

d = dict(who='tim')
#Template('Give $who $cookie').substitute(d) <--- will raise KeyError as 'cookie' not in a dictionary
print(Template('$who likes $cookies').safe_substitute(d)) # proper way

πŸ“Ÿ Output:

Johnny likes whiskey
tim likes $cookies
PreviousUnicodeNextRegular expressions

Last updated 2 years ago

Was this helpful?

This feature is described by

Format datetime objects (see :

PEP 498
docs for datetime formatting