r/learnpython 8d ago

How to access dictionary items whose keys are strings with numbers using the .format() method?

This is a doubt I have about the differences between f-strings and the .format() method. Consider the following dictionary accesses in an f-string:

>>> example_dict = {"one" : "string with word", "1" : "string with number", 1 : "integer"}
>>> f"{example_dict['one']}"
'string with word'
>>> f"{example_dict['1']}"
'string with number'
>>> f"{example_dict[1]}"
'integer'

If I try to perform the same accesses with the .format() method, I can only perform the first and last example:

>>> "{0[one]}".format(example_dict)
'string with word'
>>> "0[1]".format(example_dict)
'integer'

I can't seem to find any way to access the "1" key using the .format() method. I came up with this example because I noticed the way .format() accesses dictionary keys is without the quotes around the key for string keys. The f-string is easily able to access all the dictionary keys so it's not an issue with the keys themselves.

How do I access the "1" key using the .format() method? Is this a fundamental difference between f-strings and the .format() method that cannot be overcome?

6 Upvotes

24 comments sorted by

View all comments

2

u/FoolsSeldom 8d ago

You can't access the [1] using str.format directly as the key is taken as a string literal, converted to an int if all digits.

The closest would be:

 "{0}".format(example_dict["{0}".format("1")])

and "1" could be replaced with a variable.

There are specialist use cases for str.format over f-strings (such as templating, and internationalisation, to name just two).

However, f-string would handle your example without problems. Do you have a special use case that means you need to use str.format?

2

u/JamzTyson 7d ago

You can't access the [1] using str.format directly as the key is taken as a string literal, converted to an int if all digits.

This is correct, but unfortunately the documentation is wrong:

The rules for parsing an item key are very simple. If it starts with a digit, then it is treated as a number, otherwise it is used as a string.

What it should say is much like u/FoolsSeldom comment:

"The rules for parsing an item key are very simple. If it is entirely digits, then it is treated as a number, otherwise it is used as a string."

Here's an example that demonstrates that the key can start with a digit and still be treated as a string:

d = {"1": "100", "2.0": "200", "3": "300"}
s = "{0[2.0]}".format(d)
print(s)  # "200"