list indices must be integers or slices, not str

Frank Millman frank at chagford.com
Wed Jul 20 06:31:58 EDT 2022


On 2022-07-20 11:37 AM, Chris Angelico wrote:
> On Wed, 20 Jul 2022 at 18:34, Frank Millman <frank at chagford.com> wrote:
>>
>> Hi all
>>
>> C:\Users\E7280>python
>> Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
>> bit (AMD64)] on win32
>> Type "help", "copyright", "credits" or "license" for more information.
>>   >>>
>>   >>> x = list(range(10))
>>   >>>
>>   >>> '{x[1]}'.format(**vars())
>> '1'
>>   >>>
>>   >>> '{x[-1]}'.format(**vars())
>> Traceback (most recent call last):
>>     File "<stdin>", line 1, in <module>
>> TypeError: list indices must be integers or slices, not str
>>   >>>
>>
>> Can anyone explain this error? It seems that a negative index is deemed
>> to be a string in this case.
>>
> 
> Yeah, that does seem a little odd. What you're seeing is the same as
> this phenomenon:
> 
>>>> "{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})
> '42 ham'
>>>> "{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> KeyError: 1
> 
> But I can't find it documented anywhere that digits-only means
> numeric. The best I can find is:
> 
> https://docs.python.org/3/library/string.html#formatstrings
> """The arg_name can be followed by any number of index or attribute
> expressions. An expression of the form '.name' selects the named
> attribute using getattr(), while an expression of the form '[index]'
> does an index lookup using __getitem__()."""
> 
> and in the corresponding grammar:
> 
> field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
> index_string      ::=  <any source character except "]"> +
> 
> In other words, any sequence of characters counts as an argument, as
> long as it's not ambiguous. It doesn't seem to say that "all digits is
> interpreted as an integer, everything else is interpreted as a
> string". ISTM that a negative number should be interpreted as an
> integer too, but that might be a backward compatibility break.
> 

Thanks for investigating this further. I agree it seems odd.

As quoted above, an expression of the form '[index]' does an index 
lookup using __getitem()__.

The only __getitem__() that I can find is in the operator module, and 
that handles negative numbers just fine.

Do you think it is worth me raising an issue, if only to find out the 
rationale if there is one?

Frank


More information about the Python-list mailing list