Shaokan - 1 year ago 302
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?

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
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download