str.index() and str.find() versus only list.index()

Chris Angelico rosuav at
Tue Jul 14 07:13:41 CEST 2015

On Tue, Jul 14, 2015 at 2:58 PM, Steven D'Aprano
<steve+comp.lang.python at> wrote:
> On Tuesday 14 July 2015 14:07, Ian Kelly wrote:
>> On Mon, Jul 13, 2015 at 9:23 PM, Steven D'Aprano <steve at>
>> wrote:
>>> Correct. But rather than removing it, it would be better to take a leaf
>>> out of re.match's book and return None as the sentinel. That would
>>> eliminate the "using -1 as a valid index" bug.
>> I disagree on both counts.
>>>>> s = 'abc'
>>>>> s[None:None]
>> 'abc'
> Well wadda ya know, I just learned something new. I was thinking more along
> these lines:
> py> 'abc'[None]
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: string indices must be integers, not NoneType

Which proves that None is not a valid index, but it is a valid slice
boundary. Given that the return value will often be used for slicing
as well as indexing, it'd be good to have something that's not valid
for either. How about -1.0? It's equal to -1 in case someone uses
(str.find(...) == -1), it's less than zero in case they do
(str.find(...) < 0), and it's invalid in both slices and string
subscripts. There's no way that can break anything, right?

... oh wait. XKCD 1172. And anyone who's adding 1 to the position and
using that as a slice boundary, which will smoothly and without error
work with the beginning of the string if something isn't found (eg
s[s.find("-"):] will be everything after the first hyphen, or the
whole string if there isn't one).

>> Better IMO to just have the one non-redundant method that raises an
>> exception rather than returning anything that could possibly be
>> interpreted as a string index.
> Well, maybe, but if you got rid of str.find, the first thing people would do
> is recreate it:
> def find(*args):
>     try:
>         return str.index(*args)
>     except ValueError:
>         return -1
> Having a version of str.index that returns a sentinel is just too damn
> handy.

Same as dictionaries have [] and .get(), although find doesn't allow
you to change the sentinel.


More information about the Python-list mailing list