2

When trying out some features with the new (and awesome) python 3 literal string interpolation, I found this weird difference.

For example, using the old str.format, I can format integers with a dynamic number of digits like this:

>>> d = 5
>>> N = 3
>>> '{:0{N}d}'.format(d, N=N)
'005' 

But when I try the equivalent using literal strings, I get an error:

>>> f'{:0{N}d}'
SyntaxError: f-string: empty expression not allowed

Only by swapping the order of the arguments do I get the correct formatting

>>> f'{d:0{N}}'
'005'

This struck me as odd since I assumed I could just swap to f-strings without modifying my strings, only the calls.

What are the syntactic differences between str.format and f-string? And why does this example differ slightly?

Jonas Adler
  • 8,636
  • 2
  • 35
  • 71

1 Answers1

10

You've misunderstood what '{:0{N}d}'.format(d, N=N) does. The d in the format spec doesn't refer to the variable d; it means print an integer in base 10. Python matches that field with the d argument positionally.

When you try that with an f-string, f'{:0{N}d}', f-strings have no positional arguments. Python doesn't know what to format for that field. You need to fix your original bug and place d in front of the : so Python knows it's supposed to format d there.

For reference, the correct version with format would have been '{d:0{N}}'.format(d=d, N=N).

user2357112 supports Monica
  • 215,440
  • 22
  • 321
  • 400