0

O'Reilly's Learn Python Powerful Object Oriented Programming by Mark Lutz teaches different ways to format strings.

This following code has me confused. I am interpreting 'ham' as filling the format place marker at index zero, and yet it still pops up at index one of the outputted string. Please help me understand what is actually going on.

Here is the code:

template = '{motto}, {0} and {food}'
template.format('ham', motto='spam', food='eggs')

And here is the output:

'spam, ham and eggs'

I expected:

'ham, spam and eggs'
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
MadHatter
  • 366
  • 1
  • 7
  • 23
  • I think you're just confusing yourself. What you _said_ is correct. 'ham' is index zero, which replaces '{0}'. Thus, `{motto}, {0} and {food}` -> `{motto}, ham and {food}`. – kojiro Sep 01 '16 at 21:00
  • "I am interpreting 'ham' as filling the format place marker at index zero" - no, it fills the placeholder with a 0 in it. – user2357112 Sep 01 '16 at 21:01
  • Take a look at [pyformat.info](https://pyformat.info). – Mauro Baraldi Sep 01 '16 at 21:07
  • I'm starting to see light at the end of this little tunnel of confusion; what I had originally thought was that the string 'ham' would appear at index 0 of the final product, or the outputted string. – MadHatter Sep 01 '16 at 21:11
  • From what the OP pointed out, it appears that the {0} is just the zeroeth unnamed argument. – MadHatter Sep 01 '16 at 21:12

1 Answers1

2

The only thing you have to understand is that {0} refers to the first (zeroeth) unnamed argument sent to format(). We can see this to be the case by removing all unnamed references and trying to use a linear fill-in:

>>> "{motto}".format("boom")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'motto'

You would expect that 'boom' would fill in 'motto' if this is how it works. But, instead, format() looks for a parameter named 'motto'. The key hint here is the KeyError. Similarly, if it were just taking the sequence of parameters passed to format(), then this wouldn't error, either:

>>> "{0} {1}".format('ham', motto='eggs')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

Here, format() is looking for the second unnamed argument in the parameter list - but that doesn't exist so it gets a 'tuple index out of range' error. This is just the difference between the unnamed (which are positionally sensitive) and named arguments passed in Python.

See this post to understand the difference between these types arguments, known as 'args' and 'kwargs'.

Community
  • 1
  • 1
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • The zeroeth unnamed argument explanation helped me understand. Thank you. Now that I recall, the book did say that this example used both keyword and position. – MadHatter Sep 01 '16 at 21:16