11
votes

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.

4
Use reversed(a), it create a reverse iterator and do not modify the list. - Kien Truong
Dikei, could you give me an example as an answer? I'll gladly select it if it works. - Kelketek
reversed objects have no index() method - kosii

4 Answers

17
votes

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
6
votes

This should work:

for index, item in enumerate(reversed(a)):
    if item == "hello":
        print len(a) - index - 1
        break
4
votes

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.

0
votes

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