[Python-ideas] What are the strong use cases for str.rindex()?

Steven D'Aprano steve at pearwood.info
Wed Apr 24 20:07:43 EDT 2019


On Tue, Apr 23, 2019 at 10:28:29AM -0700, Brett Cannon wrote:

> Given "abcdefabcdefabcdef", what is the last result of "abc"?
> x.rindex("abc") will tell you.
> 
> Given [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] where is the last result of 3?
> reversed(x).index(3) will tell you (or x[::-1]).

That first version doesn't work, as list_reverseiterator objects don't 
have an index method. You're not the only person to make that error, I 
too often forget that reverse() returns an iterator, not a list.

The second is easy to get wrong, because it returns the wrong index:

  # Get the item following the last instance of spam.
  index = x[::-1].index(spam)
  print(x[index+1])

In your example, the correct index is 7 but the returned value is 2.


> Notice how with lists you can easily reverse them and still get at the
> value since you are searching per index. 

"Easily" hides a lot of copying behind the scenes. If the list is a 
non-trivial size, that can be very wasteful, especially if you're doing 
it in a loop, or hidden in a function. Don't think about the case of a 
ten element list, think of a ten-billion element list.

Personally, I don't think I've every used list.index, let alone needed 
rindex. But I think we underestimate the difficulty and cost of faking 
an rindex method from index for those who need it (if anyone does).


> But with strings, you searching by
> a subslice that can be greater than 1 in which case you can't use a similar
> approach.

Of course you can: you "just" need to reverse the substring as well.

The conversions will be even more fiddly and error-prone:

py> s = "abc spam def spam ghi"
py> s.rindex('spam') == len(s) - s[::-1].index('spam'[::-1]) - len('spam')
True

but it can be done.



-- 
Steven


More information about the Python-ideas mailing list