Search code examples
pythonpython-3.xformatting

Using variables in the format() function in Python


Is it possible to use variables in the format specifier in the format()-function in Python? I have the following code, and I need VAR to equal field_size:

def pretty_printer(*numbers):
  str_list = [str(num).lstrip('0') for num in numbers]

  field_size = max([len(string) for string in str_list])

  i = 1
  for num in numbers:
    print("Number", i, ":", format(num, 'VAR.2f')) # VAR needs to equal field_size

Solution

  • You can use the str.format() method, which lets you interpolate other variables for things like the width:

    'Number {i}: {num:{field_size}.2f}'.format(i=i, num=num, field_size=field_size)
    

    Each {} is a placeholder, filling in named values from the keyword arguments (you can use numbered positional arguments too). The part after the optional : gives the format (the second argument to the format() function, basically), and you can use more {} placeholders there to fill in parameters.

    Using numbered positions would look like this:

    'Number {0}: {1:{2}.2f}'.format(i, num, field_size)
    

    but you could also mix the two or pick different names:

    'Number {0}: {1:{width}.2f}'.format(i, num, width=field_size)
    

    If you omit the numbers and names, the fields are automatically numbered, so the following is equivalent to the preceding format:

    'Number {}: {:{width}.2f}'.format(i, num, width=field_size)
    

    Note that the whole string is a template, so things like the Number string and the colon are part of the template here.

    You need to take into account that the field size includes the decimal point, however; you may need to adjust your size to add those 3 extra characters.

    Demo:

    >>> i = 3
    >>> num = 25
    >>> field_size = 7
    >>> 'Number {i}: {num:{field_size}.2f}'.format(i=i, num=num, field_size=field_size)
    'Number 3:   25.00'
    

    Last but not least, of Python 3.6 and up, you can put the variables directly into the string literal by using a formatted string literal:

    f'Number {i}: {num:{field_size}.2f}'
    

    The advantage of using a regular string template and str.format() is that you can swap out the template, the advantage of f-strings is that makes for very readable and compact string formatting inline in the string value syntax itself.