How to find the index of the nth time an item appears in a list?

Using list comprehension and enumerate:

>>> x = [ 'w', 'e', 's', 's', 's', 'z','z', 's']
>>> [i for i, n in enumerate(x) if n == 's'][0]
2
>>> [i for i, n in enumerate(x) if n == 's'][1]
3
>>> [i for i, n in enumerate(x) if n == 's'][2]
4
>>> [i for i, n in enumerate(x) if n == 's'][3]
7

If you didn't want to store the indices for each occurrence, or wanted to work with arbitrary iterables then something like:

from itertools import islice

def nth_index(iterable, value, n):
    matches = (idx for idx, val in enumerate(iterable) if val == value)
    return next(islice(matches, n-1, n), None)

x = [ 'w', 'e', 's', 's', 's', 'z','z', 's']
idx = nth_index(x, 's', 4)
# 7

Note there's a default value of None there in the next. You may wish to change that to something else, or remove it and catch the StopIteration and raise as another more suitable exception (ValueError for instance, so that it ties up more with list.index behaviour).


For getting the index of the items:

return [index for index, char in enumerate(x) if char == 's']

For getting the character itself:

return [char for index, char in enumerate(x) if char == 's']

Or to get tuples of character/index pairs: (Thanks to falsetru for pointing out a simpler solution)

pairs = [(index, char) for index, char in enumerate(x) if char == 's']