简体   繁体   中英

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

Given:

x = ['w', 'e', 's', 's', 's', 'z','z', 's']

Each occurrence of s appears at the following indices:

1st: 2
2nd: 3
3rd: 4
4th: 7

If I do x.index('s') I will get the 1st index.

How do I get the index of the 4th s ?

Using list comprehension andenumerate :

>>> 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']
def find_nth_character(str1, substr, n):
    """find the index of the nth substr in string str1""" 
    k = 0
    for index, c in enumerate(str1):
        #print index, c, n  # test
        if c == substr:
            k += 1
            if k == n:
                return index


str1 = "B.765.A87_43.Left.9878.xx8"
substr = '.'
occurance = 4

print "%s #%d at index %d" % (substr, occurance, find_nth_character(str1, substr, occurance))

Here is a more Pythonic approach using itertools.count and a generator expression:

In [24]: def get_nth_index(lst, item, n):
    ...:     c = count()
    ...:     return next(i for i, j in enumerate(x) if j=='s' and next(c) == n-1)

Demo:

In [25]: get_nth_index(x, 's', 2)
Out[25]: 3

In [26]: get_nth_index(x, 's', 3)
Out[26]: 4

In [27]: get_nth_index(x, 's', 4)
Out[27]: 7

In [28]: get_nth_index(x, 's', 5)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-28-fc4e5e8c31ef> in <module>()
----> 1 get_nth_index(x, 's', 5)

<ipython-input-24-5394f79b3c30> in get_nth_index(lst, item, n)
      1 def get_nth_index(lst, item, n):
      2     c = count()
----> 3     return next(i for i, j in enumerate(x) if j=='s' and next(c) == n-1)

StopIteration: 

In [29]: 

As you can see, it will raise an StopIteration exception in case it can't find a match. You can also pass a default argument to next() function to return a default value instead of raising exception.

simply we can extend the functionality of the built-in list class. by inheriting it.

In [64]: class List(list):
       :     def __init__(self, *val):
       :         self.extend(list(val))
       :
       :
       :     def findidx(self, val, n=None):
       :         '''return the occurances of an object in a list'''
       :
       :         if n == None:
       :             return [i for i, v in enumerate(self) if v == val]
       :
       :         return [i for i, v in enumerate(self) if v == val][n]

and there are two ways to use this class. see in the following example to understand.

In [65]: c = List(4, 5, 6, 7, 2, 5, 4 ,4) # enter the elements of the list as a argument

In [69]: c.findidx(4, 0) # search 4's 0th(1) occurance
Out[69]: 0

In [72]: c.findidx(4, 1) # find 4's 1st(2) occurance
Out[72]: 6

or

In [66]: c.findidx(4) # find all occurances of 4
Out[66]: [0, 6, 7]

In [67]: c.findidx(4)[0] # first occurance
Out[67]: 0

In [67]: c.findidx(4)[2] # third occurance
Out[67]: 7

In [69]: c[0]# for verification
Out[69]: 4

In [70]: c[7]
Out[70]: 4

`

You can use this to find in last position

where a is the array

t=(a.index(0)+a.count(0))-1

You can increase the number to -2 or -3 to find the position of the desired number from last

NOTE: The list must be sorted. You can sort it with sort ()

eg: a.sort()

for more inbuilt function in list click here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM