Search code examples
pythonformat-stringf-string

Why does f"{11: 2d}" not pad to 2 characters?


I'm using Ipython 7.0.1 with Python 3.6.9

I want to right align numbers with the format string mini language. I use 1 and 11 as examples for 1 and 2 digit numbers which I want to pad to 2 characters total.

For zero padding everything works as expected, > is optional because it is the default:

In [0]: print(f"{1:02d}\n{11:02d}\n{1:0>2d}\n{11:0>2d}")                                         
01
11
01
11

But when I want to pad with spaces it also works as long as I leave the space out so that it defaults to space:

In [1]: print(f"{1:2d}\n{11:2d}\n{1:>2d}\n{11:>2d}")                                             
 1
11
 1
11

But If I explicitly type out the space, I am surprised by the result:

In [2]: print(f"{1: 2d}\n{11: 2d}\n{1: >2d}\n{11: >2d}")                                         
 1
 11
 1
11

Why is that?


Solution

  • Its all in the documentation...

    format_spec ::= [[fill]align][sign]...

    If a valid align value is specified, it can be preceded by a fill character

    Since both fill and sign can be space it would be ambiguous, and so space as fill must be followed by an align.

    Here's how Python interprets your last line:

    f"{1: 2d}"    #interpreted as sign therefore (accidentally) same effect  -> " 1"
    f"{11: 2d}"   #interpreted as sign therefore a leading space is inserted -> " 11"
    f"{1: >2d}"   #align is present, pad with ' '                            -> " 1"
    f"{11: >2d}"  #align is present, pad with ' ' but number long enough     -> "11"