Search code examples
pythonstring-formatting

Correct way to format integers with fixed length and space padding


I have integer numbers in the range of 0 up until (including) 100. I want to convert them to strings of a fixed length of 3 with space padding and alignment to the right.

I've tried to use the following format string, but it adds another space for three digit numbers, which makes them length 4 instead of 3.

fmt = lambda x: "{: 3d}".format(x)
[fmt(99), fmt(100)] # produces [' 99', ' 100'] instead of [' 99', '100']

Interestingly, it works as expected when zero-padding is used:

fmt = lambda x: "{:03d}".format(x) 
[fmt(99), fmt(100)] # produces ['099', '100'] as expected

Why is this? How can I fix this?

Do I really need to convert to string first?

fmt = lambda x: "{:>3s}".format(str(x))
[fmt(99), fmt(100)] # produces [' 99', '100'] as expected

Solution

  • By default, numbers are aligned to the right and padded with spaces when formatted, so you should just specify the width:

    >>> '{:3d}'.format(99)
    ' 99'
    >>> '{:3d}'.format(100)
    '100'
    

    Alternatively, you can specify both the fill character and alignment:

    >>> '{: >3d}'.format(99)
    ' 99'
    >>> '{: >3d}'.format(100)
    '100'
    

    A single space before width, however, is treated as the sign option. Quoting the documentation:

    The sign option is only valid for number types, and can be one of the following:

    '+' indicates that a sign should be used for both positive as well as negative numbers.
    '-' indicates that a sign should be used only for negative numbers (this is the default behavior).
    ' ' indicates that a leading space should be used on positive numbers, and a minus sign on negative numbers.

    That's why "{: 3d}" formats with a leading space in your examples.