Format conversion in Python, format (zero-filling, exponential notation, hexadecimal, etc.)

Money and Business

To convert (format) a number or string into various formats in Python, use the built-in function format() or the string method str.format().

In this section, we will explain how to use the following functions.

  • built-in function (e.g. in programming language)format()
  • string methodstr.format()

In addition, the format specification string for converting to the following format is explained with sample code.

  • Left-justified, Center-justified, Right-justified
  • zero fill
  • Sign (plus or minus)
  • Digit separator (comma, underscore)
  • Binary, octal, and hexadecimal numbers
  • Specify the number of digits after the decimal point
  • Significant figures (number of significant digits)
  • exponential notation
  • Percentage display

Note that since Python 3.6, f-strings (f-strings) have been added to the string method str.format() to make it more concise.

Built-in function: format()

format() is provided as a standard Python built-in function.

The outline is as follows.

  • format(value, format_spec)
    • The first argument: thevalue
      The original value. String str, number int, float, etc.
    • The second argumentformat_spec
      Format specification string. String str
    • Return value: a formatted string str

Examples are shown below. The types of format strings and how to write them are described later.

In this example, we have used numeric literals and string literals as the first argument, but of course you can use variables that contain these values.

s = format(255, '04x')
print(s)
print(type(s))
# 00ff
# <class 'str'>

print(format('center', '*^16'))
# *****center*****

String method str.format()

There is also a format() method for the string str type.

The {} in the string str that calls the format() method is called the substitution field, and is replaced by the argument of the format() method.

The format specification string should be written in the substitution field {} followed by “:”.

The return value is a formatted string str.

The equivalent process to the built-in function format() described above is as follows.

s = '{:04x}'.format(255)
print(s)
print(type(s))
# 00ff
# <class 'str'>

print('{:*^16}'.format('center'))
# *****center*****

Again, we are using numeric literals and string literals as arguments, but of course variables are also acceptable.

Specifying arguments for substitution fields

Specify arguments in order (default)

There can be multiple substitution fields {}, and by default, the method arguments are processed in order. If the format specification string in {} is omitted, it will just be converted to a string by str().

Useful for inserting variable values in a string and printing them.

print('{}-{}-{}'.format('100', '二百', 300))
# 100-二百-300

Specify a positional argument for integer values

If an integer value is specified in {}, such as {0} or {1}, the output will depend on the order of the arguments. The same number can be used repeatedly. This is useful when you want to insert the same value in a string.

print('{0}-{1}-{0}'.format('foo', 'bar'))
# foo-bar-foo

Specify keyword arguments for arbitrary names (strings)

You can also specify any name in {} and enter it as a keyword argument.

print('{day}/{month}/{year}/'.format(day=11, month=1, year=2018))
# 11/1/2018

Specify a list or dictionary as an argument

Lists and dictionaries can be specified as arguments.

Use [] to specify the index of a list or the key of a dictionary in a substitution field. Note that quotation marks “'” and “” are not used to specify dictionary keys.

If you want to use the same argument repeatedly, you need to specify an integer value or a string (name) as described above.

l = ['one', 'two', 'three']
print('{0[0]}-{0[1]}-{0[2]}'.format(l))
# one-two-three

d1 = {'name': 'Alice', 'age': 20}
d2 = {'name': 'Bob', 'age': 30}
print('{0[name]} is {0[age]} years old.\n{1[name]} is {1[age]} years old.'.format(d1, d2))
# Alice is 20 years old.
# Bob is 30 years old.

It can be expanded as a positional argument by appending * to the list and specifying it as an argument, or as a keyword argument by appending ** to the dictionary and specifying it as an argument.

l = ['one', 'two', 'three']
print('{}-{}-{}'.format(*l))
# one-two-three

d = {'name': 'Alice', 'age': 20}
print('{name} is {age} years old.'.format(**d))
# Alice is 20 years old.

Description of curly brackets {}

If you want to write curly brackets {,} in the format() method, repeat it twice like {{,}}. Note that backslashes cannot be escaped.

print('{{}}-{num}-{{{num}}}'.format(num=100))
# {}-100-{100}

formatted string

In both cases, to specify the format, write “:format string” after the integer value or name string in {}.

print('{num:x}'.format(num=255))
# ff

print('{day}/{month:02}/{year:02}/'.format(day=11, month=1, year=2018))
# 11/01/2018

In the following, we will explain how to specify the format using a format string. The sample code uses the string method str.format(), but the same format string can be used with the built-in function format(). In the built-in function format(), the format specification string is specified as the second argument.

Left-justified, Center-justified, Right-justified

You can align left-justified, center-justified, right-justified, etc. below. Specify the total number of characters as a number.

  • <
  • ^
  • >
print('left  : {:<10}'.format(100))
print('center: {:^10}'.format(100))
print('right : {:>10}'.format(100))
# left  : 100       
# center:    100    
# right :        100

You can also specify a character to be filled in. If omitted, as in the example above, it is a space.

You can use double-byte characters as long as it is a single character.

print('left  : {:*<10}'.format(100))
print('center: {:a^10}'.format(100))
print('right : {:鬼>10}'.format(100))
# left  : 100*******
# center: aaa100aaaa
# right : 鬼鬼鬼鬼鬼鬼鬼100

Right-justification with > does not take into account the sign (-,+). If you use =, the sign is followed by the specified character. If you want to specify +, write + after =. The details of sign processing are described later.

print('sign: {:0>10}'.format(-100))
print('sign: {:0=10}'.format(-100))
print('sign: {:0=+10}'.format(100))
# sign: 000000-100
# sign: -000000100
# sign: +000000100

<, ^, and > can be specified for strings, but = will result in an error ValueError. If you want to use = for a string, you need to convert it to a number using int().

# print('sign: {:0=10}'.format('-100'))
# ValueError: '=' alignment not allowed in string format specifier

print('sign: {:0=10}'.format(int('-100')))
# sign: -000000100

The same applies to floating-point numbers. Decimal points are also counted as a character.

print('left  : {:*<10}'.format(1.23))
print('center: {:a^10}'.format(1.23))
print('right : {:鬼>10}'.format(1.23))
# left  : 1.23******
# center: aaa1.23aaa
# right : 鬼鬼鬼鬼鬼鬼1.23

print('sign: {:0>10}'.format(-1.23))
print('sign: {:0=10}'.format(-1.23))
print('sign: {:0=+10}'.format(1.23))
# sign: 00000-1.23
# sign: -000001.23
# sign: +000001.23

Lists, tuples, etc. will cause an error if specified as-is, and can be converted to strings using str().

l = [0, 1]
print(type(l))
# <class 'list'>

# print('{:*^16}'.format(l))
# TypeError: unsupported format string passed to list.__format__

print(type(str(l)))
# <class 'str'>

print('{:*^16}'.format(str(l)))
# *****[0, 1]*****

For left-justified, center-justified, and right-justified, there are also dedicated string methods called ljust(), center(), and rjust().

0 fill

If you want to adjust the number of digits by zero-filling, set the character to be filled to 0 and right-justify it.

In the case of zero-filling, if the alignment symbol is omitted, it is processed as if = were specified.

print('zero padding: {:0=10}'.format(100))
print('zero padding: {:010}'.format(100))
# zero padding: 0000000100
# zero padding: 0000000100

print('zero padding: {:0=10}'.format(-100))
print('zero padding: {:010}'.format(-100))
# zero padding: -000000100
# zero padding: -000000100

=If you specify a string as an argument, as described above, you will get an error. Let's be careful.

# print('zero padding: {:010}'.format('-100'))
# ValueError: '=' alignment not allowed in string format specifier

For zero-filling, there is also a dedicated string method called zfill().

Sign (plus or minus)

By default, only negative numbers are marked with a sign (minus-).

When + is added to the formatting specification string, a sign (plus +) is also displayed for positive numbers. If a space is added, a space is displayed at the beginning of the positive number, and the number of digits is aligned with the negative number.

print('sign: {}'.format(100))
print('sign: {}'.format(-100))
# sign: 100
# sign: -100

print('sign: {:+}'.format(100))
print('sign: {:+}'.format(-100))
# sign: +100
# sign: -100

print('sign: {: }'.format(100))
print('sign: {: }'.format(-100))
# sign:  100
# sign: -100

Be careful when filling with arbitrary characters, such as the zero-filling mentioned above. The default, with no + and no spaces, fills positive numbers with one more character.

print('sign: {:06}'.format(100))
print('sign: {:06}'.format(-100))
# sign: 000100
# sign: -00100

print('sign: {:+06}'.format(100))
print('sign: {:+06}'.format(-100))
# sign: +00100
# sign: -00100

print('sign: {: 06}'.format(100))
print('sign: {: 06}'.format(-100))
# sign:  00100
# sign: -00100

If an alignment symbol is used, the sign designation symbol should be written after the alignment symbol.

print('sign: {:_>6}'.format(100))
print('sign: {:_>6}'.format(-100))
# sign: ___100
# sign: __-100

print('sign: {:_>+6}'.format(100))
print('sign: {:_>+6}'.format(-100))
# sign: __+100
# sign: __-100

print('sign: {:_> 6}'.format(100))
print('sign: {:_> 6}'.format(-100))
# sign: __ 100
# sign: __-100

Digit separator (comma, underscore)

Add a comma or underscore _ separator every three digits. This makes large numbers easier to read. Note that underscore_ is an option added in Python 3.6, so it cannot be used in earlier versions.

print('{:,}'.format(100000000))
# 100,000,000

print('{:_}'.format(100000000))
# 100_000_000

In the case of floating-point number float types, only the integer part is delimited.

print('{:,}'.format(1234.56789))
# 1,234.56789

Binary, octal, and hexadecimal numbers

Converts numerical values to binary, octal, and hexadecimal numbers for output.

  • b: Binary
  • o: Octal
  • d: Decimal
  • x,X: Hexadecimal (uppercase letters are capitalized)
print('bin: {:b}'.format(255))
print('oct: {:o}'.format(255))
print('dec: {:d}'.format(255))
print('hex: {:x}'.format(255))
print('HEX: {:X}'.format(255))
# bin: 11111111
# oct: 377
# dec: 255
# hex: ff
# HEX: FF

It can also be combined with 0-fill, and is often used to align digits in binary and hexadecimal notation.

print('bin: {:08b}'.format(255))
print('oct: {:08o}'.format(255))
print('dec: {:08d}'.format(255))
print('hex: {:08x}'.format(255))
print('HEX: {:08X}'.format(255))
# bin: 11111111
# oct: 00000377
# dec: 00000255
# hex: 000000ff
# HEX: 000000FF

Note that the number of zero-fill characters must be specified taking into account the prefix.

print('bin: {:#010b}'.format(255))
print('oct: {:#010o}'.format(255))
print('dec: {:#010d}'.format(255))
print('hex: {:#010x}'.format(255))
print('HEX: {:#010X}'.format(255))
# bin: 0b11111111
# oct: 0o00000377
# dec: 0000000255
# hex: 0x000000ff
# HEX: 0X000000FF

For binary and hexadecimal numbers, only the underscore _ digit separator can be inserted (Python 3.6 or later). 4-digit separator is used; the number of zero-filled characters must also take into account the number of underscores.

print('hex: {:08x}'.format(255))
print('hex: {:09_x}'.format(255))
print('hex: {:#011_x}'.format(255))
# hex: 000000ff
# hex: 0000_00ff
# hex: 0x0000_00ff

Only the integer type int can convert the format to binary or hexadecimal. You can use int() to convert it to a number.

# print('hex: {:08x}'.format('255'))
# ValueError: Unknown format code 'X' for object of type 'str'

print('hex: {:08x}'.format(int('255')))
# hex: 000000ff

Specify the number of digits after the decimal point

To specify the number of digits after the decimal point, do the following: n is the number of digits. The number of digits after the decimal point becomes the specified number of digits regardless of the number of digits in the integer part.
.[n]f

print('{:.2f}'.format(123.456))
print('{:.5f}'.format(123.456))
print('{:.3f}'.format(0.0001234))
# 123.46
# 123.45600
# 0.000

The left side of the decimal point can be specified as left-justified, center-justified, right-justified, or zero-filled as described above. If the number of digits of the target value is more than the specified number, nothing is done. If the number of digits in the target value is greater than the specified number of digits, nothing is done.

print('{:>12.5f}'.format(123.456))
print('{:012.5f}'.format(123.456))
print('{:06.5f}'.format(123.456))
#    123.45600
# 000123.45600
# 123.45600

If you specify a number of digits less than the original number of digits after the decimal point, the value will be rounded. Note that this is not rounding to the nearest whole number, but to an even number, e.g. 0.5 is rounded to 0.

print('{:.0f}'.format(0.4))
print('{:.0f}'.format(0.5))
print('{:.0f}'.format(0.6))
# 0
# 0
# 1

If you want to use general rounding, you can use the quantize() method of the standard library decimal.

exponential notation

When a floating-point float number is converted to a string str, it will automatically be written in exponential notation depending on the number of digits. Integer type int does not.

print('{}'.format(0.0001234))
print('{}'.format(0.00001234))
# 0.0001234
# 1.234e-05

print('{}'.format(1234000000000000.0))
print('{}'.format(12340000000000000.0))
print('{}'.format(12340000000000000000000000))
# 1234000000000000.0
# 1.234e+16
# 12340000000000000000000000

If you specify e or E in the formatting specification string, you can always convert to exponential notation. The characters used in the output will be e and E, respectively.

print('{:e}'.format(0.0001234))
print('{:E}'.format(0.0001234))
# 1.234000e-04
# 1.234000E-04

It is also possible to specify the number of digits after the decimal point. The integer part will always be one digit and the decimal point will be the specified number of digits.

print('{:.5e}'.format(0.0001234))
print('{:.2E}'.format(0.0001234))
# 1.23400e-04
# 1.23E-04

print('{:.5e}'.format(987.65))
print('{:.2E}'.format(987.65))
# 9.87650e+02
# 9.88E+02

Note that if you specify left-justified, center-justified, right-justified, or zero-filled, e-, E+, etc. will also be counted as digits (characters).

print('{:>12.5e}'.format(987.65))
print('{:012.2E}'.format(987.65))
#  9.87650e+02
# 00009.88E+02

Significant figures (number of significant digits)

You can specify the overall number of digits by doing the following Depending on the result, exponential notation will be used automatically. Note that trailing zeros after the decimal point will be omitted.
.[n]g

print('{:.2g}'.format(123.456))
print('{:.3g}'.format(123.456))
print('{:.8g}'.format(123.456))
print('{:.3g}'.format(0.0001234))
# 1.2e+02
# 123
# 123.456
# 0.000123

If you omit g, the output will not be an integer. g is the same in most cases, but only in cases where the output is an integer.

print('{:.2}'.format(123.456))
print('{:.3}'.format(123.456))
print('{:.8}'.format(123.456))
print('{:.3}'.format(0.0001234))
# 1.2e+02
# 1.23e+02
# 123.456
# 0.000123

If we process the same value, we get the following respectively.

print('{:.3f}'.format(123.456))
print('{:.3e}'.format(123.456))
print('{:.3g}'.format(123.456))
print('{:.3}'.format(123.456))
# 123.456
# 1.235e+02
# 123
# 1.23e+02

print('{:.8f}'.format(123.456))
print('{:.8e}'.format(123.456))
print('{:.8g}'.format(123.456))
print('{:.8}'.format(123.456))
# 123.45600000
# 1.23456000e+02
# 123.456
# 123.456

In the case of g or if it is omitted, the trailing zeros after the decimal point are omitted, so if you want to output the same number of significant figures (number of significant digits), use the exponential notation of e or E. The integer part is always one digit and the decimal point is the specified number of digits, so if you want to output n significant digits, just specify n-1.

print('{:.4e}'.format(123.456))
print('{:.4e}'.format(0.000012345))
print('{:.4e}'.format(12))
# 1.2346e+02
# 1.2345e-05
# 1.2000e+01

Percentage display

If % is specified in the formatting specification string, the value of the numeric float or int is multiplied by 100 and converted to a string with %.

It is also possible to specify the number of digits after the decimal point. The default is six digits after the decimal point. Left-justify, center-justify, right-justify, and zero-fill are also available. The % is also counted as a character.

print('{:%}'.format(0.12345))
print('{:.2%}'.format(0.12345))
# 12.345000%
# 12.35%

print('{:%}'.format(10))
print('{:.2%}'.format(10))
# 1000.000000%
# 1000.00%

print('{:>7.2%}'.format(0.12345))
print('{:07.2%}'.format(0.12345))
#  12.35%
# 012.35%