Shaokan Shaokan - 3 months ago 48
Python Question

How to find the last occurrence of an item in a Python list

Say I have this list:

li = ["a", "b", "a", "c", "x", "d", "a", "6"]


As far as help showed me, there is not a builtin function that returns the last occurrence of a string (like the reverse of
index
). So basically, how can I find the last occurrence of
"a"
in the given list?

wim wim
Answer

If you are actually using just single letters like shown in your example, then ''.join(li).rfind('a') would work nicely. It will return -1 if 'a' is not in the list.

For the general case you could use:

(len(li) - 1) - li[::-1].index('a')

It will raise ValueError if 'a' is not in the list.

For the case where li is a very long list, it may be performant to do this with a 'lazy' approach using itertools:

import itertools as it
indices = xrange(len(li) - 1, 0, -1)
gen = it.izip(indices, reversed(li))
next(i for i,value in gen if value == 'a')

Here are some timing comparisons on python 2.7.6:

>>> li = list(string.ascii_lowercase * 100)
>>> timeit ''.join(li).rfind('a')
10000 loops, best of 3: 23.9 µs per loop
>>> timeit (len(li) - 1) - li[::-1].index('a')
100000 loops, best of 3: 6.02 µs per loop
>>> timeit next(i for i,v in it.izip(xrange(len(li)-1, 0, -1), reversed(li)) if v == 'a')
100000 loops, best of 3: 2.52 µs per loop

Timings on python 3.4.3, where we don't actually need itertools:

>>> timeit ''.join(li).rfind('a')
100000 loops, best of 3: 19 µs per loop
>>> timeit (len(li) - 1) - li[::-1].index('a')
100000 loops, best of 3: 5.52 µs per loop
>>> timeit next(i for i,v in zip(range(len(li)-1, 0, -1), reversed(li)) if v == 'a')
100000 loops, best of 3: 2.96 µs per loop
Comments