Thank you! It is running smoothly now
I had a strong feeling that the solution would be verrry simple…but I over-thought the problem. Why should there be no space in the curly brackets?
That is a good question which lacks a good answer in the Python
documentation.
My personal feeling is that it is likely that the implementation is
looking at the bit between the “{ }” and treating it as follows:
-
empty string - an implied positional value, so the first “{}” means
the first position value in your arguments to format().
-
digits: indicating a particular positional value eg “{0}” means_
the first position value in your arguments to format().
-
identifier (and following .attr or [index] suffixes): look up
identifier in the keyword arguments to format(), then follow whatever
.attr or [index] things might be added
eg {foo.x[1]} looks up “foo” in the keyword arguments, looks up .x on
that indexes that in turn with 1.
-
falls back to the syntax for “index” above
The Python docs do not say that last step, which I am inferring.
If you go to the Python docs at: 3.12.1 Documentation
and go to: the index (top right), “F” (for “format”), and find “format”
in the listing and follow the “(str method)” link (because you’re using
the str.format method in your code), you land here:
https://docs.python.org/3/library/stdtypes.html#str.format
That refers to the Format String Syntax, which links to here:
https://docs.python.org/3/library/string.html#formatstrings
which says that the “arg_name” is either an identifier or digits (cases
3 and 2 above respectively). But what about “{ }”?
That’s a space between the brackets, so I think it is treating that as
the string " ". In the “[element_index]” part of that grammar it says
that element_index may be index_string, and index_string is defined as:
index_string ::= <any source character except "]"> +
This actually lets you write stuff like:
{foo[bare string here]}
to index foo with “bare string here”.
I think that if the bit between “{}” is not (a) empty (b) an
identifier or (c) digits then Python is falling back to treating it like
index_string, and looking that string up in the keyword arguments.
You’ve got no keyword arguments, so " " fails to be found, so the
KeyError.
The Python format string documentation is complicated and broken up into
several pieces.
The author had examples in his book and his curly brackets had spaces.
Could it have something to do with the version?
It could. This may represent a change to the implementation of format
strings over time. Notice that the above docs have some “Changed in
version” bits. Those notes are added when things change, but clearly are
not always added (tiny changes happen al the time in the code, so the
noise in the docs would be extreme).
Cheers,
Cameron Simpson cs@cskk.id.au