Find the index of the n'th item in a list

后端 未结 11 1864
余生分开走
余生分开走 2020-12-13 00:04

I want to find the index of the n\'th occurrence of an item in a list. e.g.,

x=[False,True,True,False,True,False,True,False,False,False,True,False,True]


        
相关标签:
11条回答
  • 2020-12-13 00:41

    A solution that first creates a list object and returns the nth-1 element of this list : function occurence()

    And a solution that fulfill functional programmers'dreams too, I think, using generators, because I love them : function occur()

    S = 'stackoverflow.com is a fantastic amazing site'
    print 'object S is string %r' % S
    print "indexes of 'a' in S :",[indx for indx,elem in enumerate(S) if elem=='a']
    
    def occurence(itrbl,x,nth):
        return [indx for indx,elem in enumerate(itrbl)
                if elem==x ][nth-1] if x in itrbl \
               else None
    
    def occur(itrbl,x,nth):
        return (i for pos,i in enumerate(indx for indx,elem in enumerate(itrbl)
                                         if elem==x)
                if pos==nth-1).next() if x in itrbl\
                else   None
    
    print "\noccurence(S,'a',4th) ==",occurence(S,'a',4)
    print "\noccur(S,'a',4th) ==",occur(S,'a',4)
    

    result

    object S is string 'stackoverflow.com is a fantastic amazing site'
    indexes of 'a' in S : [2, 21, 24, 27, 33, 35]
    
    occur(S,'a',4th) == 27
    
    occurence(S,'a',4th) == 27
    

    The second solution seems complex but it isn't really. It doesn't need to run completely through the iterable: the process stops as soon as the wanted occurence is found.

    0 讨论(0)
  • 2020-12-13 00:42

    if efficiency is a concern i think its better to iterate the normally ( O(N) ) instead of list comprehension which takes O(L) where L is length of list

    Example : Consider a very huge list and you want to find the first occurence N=1 it is obviously better to stop as soon as you find the first occurence

    count = 0
    for index,i in enumerate(L):
        if i:
            count = count + 1
            if count==N:
                return index
    
    0 讨论(0)
  • 2020-12-13 00:43

    I think this should work.

    def get_nth_occurrence_of_specific_term(my_list, term, n):
        assert type(n) is int and n > 0
        start = -1
        for i in range(n):
            if term not in my_list[start + 1:]:
                return -1
            start = my_list.index(term, start + 1)
        return start
    
    0 讨论(0)
  • 2020-12-13 00:46

    You could use count:

    from itertools import count
    
    x = [False, True, True, False, True, False, True, False, False, False, True, False, True]
    
    
    def nth_index(n, item, iterable):
        counter = count(1)
        return next((i for i, e in enumerate(iterable) if e == item and next(counter) == n), -1)
    
    
    print(nth_index(3, True, x))
    

    Output

    4
    

    The idea is that due to the short-circuit nature of e == item and next(counter) == n), the expression next(counter) == n only gets evaluated when e == item so you are only counting the elements equals to item.

    0 讨论(0)
  • 2020-12-13 00:50

    The answer from @Taymon using list.index was great.

    FWIW, here's a functional approach using the itertools module. It works with any iterable input, not just lists:

    >>> from itertools import compress, count, imap, islice
    >>> from functools import partial
    >>> from operator import eq
    
    >>> def nth_item(n, item, iterable):
            indicies = compress(count(), imap(partial(eq, item), iterable))
            return next(islice(indicies, n, None), -1)
    

    The example is nice because it shows off how to effectively combine Python's functional toolset. Note, that once the pipeline is set-up, there are no trips around Python's eval loop -- everything gets done at C speed, with a tiny memory footprint, with lazy evaluation, with no variable assignments, and with separately testable components. IOW, it is everything functional programmers dream about :-)

    Sample run:

    >>> x = [False,True,True,False,True,False,True,False,False,False,True,False,True]
    >>> nth_item(50, True, x)
    -1
    >>> nth_item(0, True, x)
    1
    >>> nth_item(1, True, x)
    2
    >>> nth_item(2, True, x)
    4
    >>> nth_item(3, True, x)
    6
    
    0 讨论(0)
  • 2020-12-13 00:50

    I can't say for certain that this is the fastest way, but I imagine it'd be pretty good:

    i = -1
    for j in xrange(n):
        i = x.index(True, i + 1)
    

    The answer is i.

    0 讨论(0)
提交回复
热议问题