Signup/Sign In

str.format() Method in Python- Part 2

Posted in Programming   LAST UPDATED: SEPTEMBER 15, 2021

    In one of the previous posts, we saw different ways of formatting data using the format() method. If you haven't seen that post, it is strongly suggested to visit that page and understand the concepts in its entirety from the beginning. In this post, we will understand more about formatting strings where we will be using single formatter, multiple formatters, with keywords and positional arguments, conversion of integers to different types, formatting class objects and dictionary objects.

    So hold your breath and be ready for a deep dive.

    1. Using single string formatter {}

    A single formatter replaces one position specified using curly braces {} in a string with a given value.

    Syntax:

    {}.format(value)

    The value argument passed to the format method can be a string, integer, floating-point, character or a variable. This value is placed in the place of the placeholder ({}) and concatenated with the remaining part of the string and returned as a result.

    Time for an example:

    The first print statement demonstrates replacing placeholder {} with a value. The second print statement defines a string and then calls the format function on the string by passing a string value to the format method. The third print statement formats a string to add a numeric value in it.

    print ("{} is an author at Studytonight".format("Smriti"))
    str = "{} is amazing"
    print (str.format("Studytonight"))
    print ("Studytonight has {} characters!".format(12))

    Output:

    Smriti is an author at Studytonight
    Studytonight is amazing
    Studytonight has 12 characters!


    2. Multiple formatters

    Instead of using one curly bracket placeholder {}, multiple placeholders can also be used to replace them with multiple values in a given string. The placeholders are replaced in the same order in which the values are specified i.e, the placeholders are replaced with values starting from index 0.

    The only condition in multiple formatting is that the number of placeholders and the number of values specified should be equal.

    Time for an example:

    my_string = "{} is a {} that offers awesome {}."
    print (my_string.format("Studytonight", "website", "content"))
    
    my_str = "{} has {} characters." # Formatter with multiple placeholder
    print(my_str.format("Studytonight", 12))

    Output:

    Studytonight is a website that offers awesome content.
    Studytonight has 12 characters.

    What if the number of values is less than the number of placeholders?

    This raises an IndexError, since Python doesn't find a suitable index for a specific placeholder in the string.

    my_string = "{} is a {} that offers awesome {} {}."
    print (my_string.format("Studytonight", "website", "content"))

    Output:

    IndexError: tuple index out of range

    What if the number of values is greater than the number of placeholders?

    This wouldn't make any difference since the placeholders are replaced by values beginning from index 0 and once all the placeholders are filled, Python doesn't look for replacing any more values if there are no more placeholders to replace.

    my_string = "{} is a {} that offers awesome {}."
    print (my_string.format("Studytonight", "website", "content", "Hello"))

    Output:

    Studytonight is a website that offers awesome content.


    3. Formatters with Positional arguments

    The values inside the format method are tuples, which is why they can be accessed using an index. Since tuples are based on zero-index, the first element can be accessed using tuple_name[0], and so on. These indices can be passed as values for placeholders in the format method.

    Note: If no value is provided for the placeholders {}, Python's format method replaces the values passed to the format method in the same order in which they were specified in the format method.

    When we say, positional arguments, we mean that if I have to format a string and add 3 values in place of 3 placeholders, by default the placeholders are replaced in order, but by specifying positional arguments I can replace the placeholders with any value I want, all I have to do is mention the index value of the tuple in which the values are stored.

    Time for an example:

    The first print statement uses the indices of the tuple to assign values to the placeholders.

    The second print statement indicates that the indices can be mentioned in any order, and this corresponds to the order in which the values are assigned to placeholders inside the format method. Basically, {1} maps to the second element of the tuple(index starting from 0) inside the format method, i.e 'Everybody'. Similarly, 0 maps to the 0th index of the tuple, which holds element 'Studytonight'.

    The third statement implies the same thing as that of the second statement but uses 4 positional arguments to make the point clear.

    print("{0} love {1}!!".format("I", "Studytonight"))
    print("{1} loves {0}!!".format("Studytonight", "Everybody"))
    print("{2} is the most widely {3} after {1} {0}".format("language","programming", "Python", "sought"))

    Output:

    I love Studytonight!!
    Everybody loves Studytonight!!
    Python is the most widely sought after programming language.


    4. Formatters with the keyword argument

    The placeholder with the format method can also have a key name inside the curly braces and this placeholder key is assigned with a value inside the format function.

    Time for an example:

    print("{st}".format(st ="Studytonight"))
    print("{st} has {number_of_char} characters in it.".format(st ="Studytonight", number_of_char = 12))

    Output:

    Studytonight
    Studytonight has 12 characters in it.


    5. Formatters with both positional and keyword arguments

    The formatters with positional arguments as well as formatters with keyword arguments can be combined and passed together when required. The below code demonstrates how the positional and keyword arguments can be passed to the format method.

    Note: It is important to understand that the keyword argument has to be provided at the end, and all the positional arguments have to be provided prior to specifying the keyword argument, else you will get an error.

    Time for an example:

    print("{st} is a great {1} for {0}".format("everyone", "portal", st ="Studytonight"))
    print("{st} is a great {1} for {0} {2}".format("technology", "portal", "enthusiasts", st ="Studytonight"))

    Output:

    Studytonight is a great portal for everyone
    Studytonight is a great portal for technology enthusiasts

    Result of passing positional argument after keyword argument:

    print("{st} is a great {1} for {0} {3}".format("technology", "portal", st ="Studytonight", "enthusiasts"))

    Output:

    SyntaxError: positional argument follows keyword argument


    6. Type specification for number formatting

    Apart from specifying the index or variable name for the placeholder, i.e curly braces {}, index of argument and conversion code of the data type can be specified to the format method, when you are dealing with numerical values.

    Syntax to specify the type:

    string{field_name:conversion}.format(value)

    Here, field_name refers to the index of the argument that is passed to the format method and conversion refers to the conversion code of that data type.

    Here are a few conversion codes for your reference:

    c - character
    b - binary
    d - decimal integers (base-10)
    f - floating-point display (default is 6)
    F - Similar to f, but displays 'nan' as NAN, and 'inf' as INF
    o - octal
    x - hexadecimal with lowercase letters after 9
    X - hexadecimal with uppercase letters after 9
    s - strings
    e - exponent notation
    g - general format, which rounds numbers up to 6 significant digits (p) by fault (p is precision which can be changed)
    % - Multiplies the value by 100 and appends a '%' to the end.

    Time for an example:

    Along with the positional argument (index), a conversion code (.1f) has been sent to the format method. This .1f indicates that the format function must display the data with 1 digit after the decimal in floating point (f).

    The second print statement demonstrates that if d (integer's) conversion code is passed and the placeholder value is a floating point number, a ValueError is raised.

    print("The temperature outside is {0:.1f} farenheit !".format(200.380))
    print("The temperature outside is {0:d} farenheit !".format(200.380))

    Output:

    The temperature outside is 200.4 Fahrenheit!
    ValueError: Unknown format code 'd' for object of type 'float'

    The conversion codes in the format method can be used to convert from one type to another. Here is an example:

    print("The {0} of 247 is {1:o}".format("octal", 247))   # Converting to octal
    print ("I secured {0:f}% {1}!!". format(99, "percent"))
    print ("My CGPA in this {0} was {1:.2f}%".format("subject", 89.457932))   # Limiting the precision of a decimal number
    print ("My CGPA in this {0} was {1:.0f}%".format("class", 89.345675))   # Removing decimal places
    print("The {0} conversion of 89 is {1:b}".format("binary", 100))   # Converting integer to binary

    Output:

    The octal of 247 is 367
    I secured 99.000000% percent!!
    My CGPA in this subject was 89.46%
    My CGPA in this class was 89%
    The binary conversion of 89 is 1100100


    7. Formatting string and integers

    While formatting strings, it is essential to remember that they are left-justified. But this can be easily changed by specifying alignment format specifier. Here is an example:

    ^ - align to the center

    < - align to the left

    > - align to the right

    = - The sign (+ or -) is moved to the leftmost position

    Time for an example:

    While formatting integers, it is essential to remember that they are right-justified. Here is an example demonstrating the before and after of formatting integers.

    print(4, 3 ** 2, 2 ** 3, 1 ** 4)
    print("{:5d} {:6d} {:5d} {:6d}".format(4, 3 ** 2, 2 ** 3, 1 ** 4))
    print("{:6d}".format(1234))  # When number is longer than the padding formatter, it doesn't work
    print("{:9.3f}".format(45.6789034))  # Formatting floats
    print("{:06d}".format(98))  # Numbers with minimum width, placed with 0's
    print("{:08.7f}".format(56.37603))  # Floating number format, placed with 0's

    Output:

    4 9 8 1
    4 9 8 1
    1234
    45.679
    000098
    56.3760300

    Below is another example showing how formatting can be done on signed values:

    print("{:+f} {:+f}".format(34.12, -12.23))
    print("{:-f} {:-f}".format(12.23, -12.23))
    print("{: f} {: f}".format(12.23, -12.23))  # Blank space indicates + sign

    Output:

    +34.120000 -12.230000
    12.230000 -12.230000
     12.230000 -12.230000

    The format method can also be used to truncate string objects. Below is an example:

    my_str = "StudyTonight"
    print("{:.5}".format(my_str))
    print("{:10.5}".format(my_str))  # Truncating and padding 
    print("{:^25.10}".format(my_str))

    Output:

    Study
    Study     
           StudyTonig        

    To learn more about formatting numbers using format specifiers, we have a separate detailed post for it.


    8. Formatting class members

    As mentioned earlier, the format method under the hood calls its __format__ with that specific argument. This means classes too can have their own custom formatting. This can be done to customize how the class attributes are displayed.

    In case you wish to use the format method as is, without customizing it, and an instance of the class is passed to the format method, Python 2 would use __str__ or __repr__ return type to determine how to print the data. On the other hand, if Python 3 is used to pass an instance of the class to the format method, the __format__ must be defined specifically in that class.

    Syntax to format classes:

    object.__format__(self, format_specification)

    It is called by the format method which returns a formatted representation of the value passed. The format_spec is a parameter that specifies the type in which data needs to be formatted. This depends completely on the type which implements __format__ method. Most classes use one or other built-in data types.

    The value returned is a string object.

    In Python 3.4 version, the __format__ method was changed to raise a TypeError in case of passing a non-empty string.

    In Python 3.7 version, the object.__format(x, '') is equivalent to str(x) instead of format(str(self), ''). Below is the demonstration.

    class Website:
        name = "Studytonight"
        characters = 12
    print("{st.name}'s number of characters is: {st.characters}".format(st=Website()))

    Output:

    Studytonight's number of characters is: 12


    9. Formatting dictionary data structure

    Dictionary members are looked up with the help of the __getitem__ method in the form of dictionary_name[index]. The dictionary can be passed as a parameter to the format method.

    Time for an example:

    my_dict = {'Website': 'Studytonight', 'characters': 12}
    print("{m_d[Website]}'s number of characters is: {m_d[characters]}".format(m_d=my_dict))

    Output:

    Studytonight's number of characters is: 12


    Conclusion:

    In this post, we understood the various ways in which format method can be used with classes, strings, integers, and dictionaries. Don't forget to experiment with the code on your IDE.

    You may also like:

    About the author:
    I love writing about Python and have more than 5 years of professional experience in Python development. I like sharing about various standard libraries in Python and other Python Modules.
    Tags:PythonPython format
    IF YOU LIKE IT, THEN SHARE IT
     

    RELATED POSTS