Another Visit To String Formatting (Python)

Updated vegaseat 6 Tallied Votes 929 Views Share

We have had several snippets on the format() function. This one gives a condensed overview of the many options you have.

ddanbe commented: Nice overview. +15
mattster commented: Looks good ;) +7
''' format_miscellaneous101.py
explore string formatting (Python27+)

tested with Python27 and Python34
'''

# field width
print("|{:8d}|".format(77))   # right aligned  |      77| 
print("|{:<8d}|".format(77))  # left aligned   |77      |
print("|{:^8d}|".format(77))  # center aligned |   77   |
# external field width
width = 10
print("|{:{w}d}|".format(77, w = width))  # |        77|

print("{:0.2e}".format(1000)) # sci notation 1.00e+03
print("{:0.2%}".format(0.25)) # percent format 25.00%
print("{:,}".format(1000000)) # comma separator 1,000,000
print("{:x<4d}".format(77))   # right pad with x --> 77xx
print("{:0>4d}".format(77))   # left pad with 0 --> 0077

# number of decimals
print("{:f}".format(3.141)) # default 6 decimals 3.141000
print("|{:10f}|".format(355/113.0)) # |  3.141593|
print("{:.2f}".format(3.141)) # 2 decimals 3.14
print("{:.2f}".format(77))    # 2 decimals 77.00
print("{:.0f}".format(2.718)) # no decimals 3

# external number of decimals
decimals = 8
print("{:0.{d}f}".format(355/113.0, d=decimals)) # 3.14159292
# external field width, decimals and specifier
sf = "|{:{w}.{d}{s}}|".format(2.34, w = 10, d=4, s='f')
print(sf)  # |    2.3400|

# + (also does negative numbers)
print("{:+.2f}".format(3.141))   # +3.14
print("{:+.2f}".format(-3.141))  # -3.14

# character fill
print("{:{fill}>8d}".format(77, fill='_')) # ______77

print("{:d}".format(21))   # decimal 21
print("{:x}".format(21))   # hexadecimal 15
print("{:#x}".format(21))  # hexadecimal 0x15
print("{:o}".format(21))   # octal 25
print("{:b}".format(21))   # binary 10101
print("{:#b}".format(21))  # binary 0b10101
print("{:s}".format('A'))  # A
# for strings using {:s} is optional
print("{}".format('A'))    # A
# a number without a specifier is treated as a string
print("{}".format(3.1416))  # 3.1416

# placement specifiers (integer)
print("Oct{0:o} = Dec{0:d}".format(25))  # Oct31 = Dec25
# this would give an IndexError
#print("Oct{:o} = Dec{:d}".format(25))
s1 = "dark"
s2 = "mouse"
s3 = "cat"
sf1 = "It was {0} when the {1} jumped over the {2}!"
print(sf1.format(s1, s2, s3))
# without the placement specifier the arguments are taken in order
sf2 = "It was {} when the {} jumped over the {}!"
print(sf2.format(s1, s2, s3))
# mix up the order
sf3 = "The {2} jumped over the {1} in the {0}!"
print(sf3.format(s1, s2, s3))
'''
It was dark when the mouse jumped over the cat!
It was dark when the mouse jumped over the cat!
The cat jumped over the mouse in the dark!
'''

# see also https://mkaz.com/2012/10/10/python-string-format/
# using same placement specifier for one argument
print("Oh {0}, {0}! Wherefore art thou {0}?".format("Romeo"))
'''
Oh Romeo, Romeo! Wherefore art thou Romeo?
'''

# defining formats
email_f = "Your email address was {email}".format

# then use format elsewhere
print(email_f(email="bob@example.com"))
'''
Your email address was bob@example.com
'''

# escape the { and } braces this way
print("The {} set is often represented as {{0}}".format("empty"))
'''
The empty set is often represented as {0}
'''

# using named args
sf = "Bob {verb} the {object} off the {place}"
print(sf.format(verb="took", object="cheese", place="table"))
'''
Bob took the cheese off the table
'''

# using local dictionary vars()
name = "Harry"
age = 35

#print(vars())
print("{name} is {age} years old".format(**vars()))
'''
Harry is 35 years old
'''

print('-'*40)

# create a date and time string
import datetime as dt
now = dt.datetime.now()
# use datetime %specifiers
date_str = format(now, "%A %B %d, %Y")
time_str = format(now, "%H:%M:%S")
print("The present date is {}".format(date_str))
print("The present time is {}".format(time_str))
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Print a simple table using the string format function ...

''' format_table101.py
an example of a table created with format()
'''

# name,age,weight lines read from a csv file
data_str = """\
Heidi Kalumpa,36,127
Frank Maruco,27,234
Larry Pestraus,19,315
Serge Romanowski,59,147
Carolus Arm,94,102
Michel Sargnagel,21,175"""

# create a list of [name, age, weight] lists
data_list = [line.split(',') for line in data_str.split('\n')]
#print(data_list)  # test

# header list
header = ['Name', 'Age', 'Weight']

sf = "{:<18s} {:>6s} {:>7s}"
print(sf.format(*header))
print('-'*33)
for sublist in data_list:
    # unpack the sublist with *
    print(sf.format(*sublist))
print('-'*33)

''' result ...
Name                  Age  Weight
---------------------------------
Heidi Kalumpa          36     127
Frank Maruco           27     234
Larry Pestraus         19     315
Serge Romanowski       59     147
Carolus Arm            94     102
Michel Sargnagel       21     175
---------------------------------
'''
commented: Good one +6
commented: Thanks. +0
Gribouillis 1,391 Programming Explorer Team Colleague

This example shows how to use the __format__ method to fine tune the format of an instance (here a dice) in formatting statements.

#-*-coding: utf8-*- python 2 or 3
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
from random import choice
try: chr = unichr
except: pass

class Dice(object):
    _values = (1, 2, 3, 4, 5, 6)
    _symbols = tuple(chr(i) for i in range(9856, 9862))
    def __init__(self, value=1):
        assert value in self._values
        self.value = value

    def roll(self):
        self.value = choice(self._values)

    def __format__(self, spec):
        if spec == 'pic': # picture format (a unicode character)
            return self._symbols[self.value-1]
        elif spec == 'd': # integer format
            return str(self.value)
        elif spec == 'r': # repr
            return 'Dice({})'.format(self.value)
        else: # default case
            return super(Dice, self).__format__(spec)

    def __repr__(self):
        return '{:r}'.format(self)

if __name__ == '__main__':
    for i in range(4):
        d = Dice()
        d.roll()
        print('This dice is {x:r}, its value is {x:d}, its picture is {x:pic}'.format(x=d))

"""my output -->
This dice is Dice(4), its value is 4, its picture is ⚃
This dice is Dice(3), its value is 3, its picture is ⚂
This dice is Dice(2), its value is 2, its picture is ⚁
This dice is Dice(6), its value is 6, its picture is ⚅
"""

Edit: hm unicode dice chars don't show correctly.
Edit: added default case.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

@Gribouillis,
dice symbols work fine using Idle and Python34 on a Windows machine.
Thank you for the __format__ method.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Here we use function format() to print out a dictionary as a table ...

''' dict_print_table101.py
use format() to print the contents of a dictionary as a table
adjust the table to maximum length of any key
'''

food_dict = {
'almond milk' : 3.29,
'butter' : 2.90,
'bread' : 1.67,
'cheese' : 4.67,
'peanut butter' : 2.48,
'grape jelly' : 177
}

# find max length of food keys
max_len = max(len(food) for food in food_dict)

# food keys will print in dictionary hash order
for food, price in food_dict.items():
    print("{fd:{mx}} = ${pr:4.2f}".format(
        fd=food, pr=price, mx=max_len))

''' result ...
butter        = $2.90
cheese        = $4.67
almond milk   = $3.29
grape jelly   = $177.00
peanut butter = $2.48
bread         = $1.67
'''

print('-'*30)

# use the dictionary key directly to print one item
sf = "Bread costs ${bread:4.2f}"
print(sf.format(**food_dict))

''' result ...
Bread costs $1.67
'''
BustACode 15 Light Poster

Great stuff.
I went through it and saved it for future reference. Great cheat sheet.

Thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.