13

Is there an efficient way to find the last matching item in a list? When working with strings, you can find the last item with rindex:

    >>> a="GEORGE"
    >>> a.rindex("G")
    4

...But this method doesn't exist for lists:

    >>> a=[ "hello", "hello", "Hi." ]
    >>> a.rindex("hello")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'list' object has no attribute 'rindex'

Is there a way to get this without having to construct a big loop? I'd prefer not to use the reverse method if it can be avoided, as the order is important and I'd also have to do a bit of extra math to find out where the object /would/ have been. This seems wasteful.

Edit:

To clarify, I need the index number of this item.

Kelketek
  • 2,406
  • 5
  • 21
  • 28

4 Answers4

20

How about:

len(a) - a[-1::-1].index("hello") - 1

Edit (put in function as suggested):

def listRightIndex(alist, value):
    return len(alist) - alist[-1::-1].index(value) -1
EwyynTomato
  • 4,009
  • 1
  • 31
  • 39
  • 8
    This isn't a good solution. It works, but creates a copy of the whole list. Not reasonable for the use-case. – Guy Oct 10 '18 at 08:45
10

This should work:

for index, item in enumerate(reversed(a)):
    if item == "hello":
        print len(a) - index - 1
        break
Kien Truong
  • 11,179
  • 2
  • 30
  • 36
4

I wrote a straightforward Python function, and here it is:

def list_rindex(lst, item):
    """
    Find first place item occurs in list, but starting at end of list.
    Return index of item in list, or -1 if item not found in the list.
    """
    i_max = len(lst)
    i_limit = -i_max
    i = -1
    while i >= i_limit:
        if lst[i] == item:
            return i_max + i
        i -= 1
    return -1

But while I was testing it, EwyynTomato posted a better answer. Use the "slicing" machinery to reverse the list and use the .index() method.

steveha
  • 74,789
  • 21
  • 92
  • 117
1

Supports start:

def rindex(lst, val, start=None):
    if start is None:
        start = len(lst)-1
    for i in xrange(start,-1,-1):
        if lst[i] == val:
            return i
mpen
  • 272,448
  • 266
  • 850
  • 1,236