Skip to content Skip to sidebar Skip to footer

In Python, How Can I Find The Index Of The First Item In A List That Is Not Some Value?

Python's list type has an index(x) method. It takes a single parameter x, and returns the (integer) index of the first item in the list that has the value x. Basically, I need to i

Solution 1:

Exiting at the first match is really easy: instead of computing a full list comprehension (then tossing away everything except the first item), use next over a genexp. Assuming for example that you want -1 when no item satisfies the condition of being != x,

returnnext((i for i, v inenumerate(L) if v != x), -1)

This is Python 2.6 syntax; if you're stuck with 2.5 or earlier, .next() is a method of the genexp (or other iterator) and doesn't accept a default value like the -1 above (so if you don't want to see a StopIteration exception you'll have to use a try/except). But then, there is a reason more releases were made after 2.5 -- continuous improvement of the language and its built-ins!-)

Solution 2:

Using a list comprehension when you only need the first just feels slimy (to me). Use a for-loop and exit early.

>>>lst = [None, None, None, "foo", None]>>>for i, item inenumerate(lst):...if item: break...else:...print"not found"...>>>i
3

Solution 3:

enumerate() returns an iterator that yields a tuple of the current index of the iterable as well as the item itself.

Solution 4:

[i for i, x in enumerate(my_list) if x != value][0]

If you're not sure whether there's a non-matching item, use this instead:

match = [i fori, x inenumerate(my_list) if x != value]
ifmatch:
    i = match[0]
    # i is your number.

You can make this even more "functional" with itertools, but you will soon reach the point where a simple for loop is better. Even the above solutions aren't as efficient as a for loop, since they construct a list of all non-matching indices before you pull the one of interest.

Solution 5:

A silly itertools-based solution:)

import itertools as it, operator as op, functools as ft

defindex_ne(item, sequence):
    sequence= iter(sequence)
    counter= it.count(-1) # start counting at -1
    pairs= it.izip(sequence, counter) # pair them
    get_1st= it.imap(op.itemgetter(0), pairs) # drop the used counter value
    ne_scanner= it.ifilter(ft.partial(op.ne, item), get_1st) # get only not-equalstry:
        ne_scanner.next() # this should be the first not equalexcept StopIteration:
        returnNone# or raise some exception, all items equal to itemelse:
        return counter.next() # should be the index of the not-equal itemif __name__ == "__main__":
    import random

    test_data= [0]*20print"failure", index_ne(0, test_data)

    index= random.randrange(len(test_data))
    test_data[index]= 1print"success:", index_ne(0, test_data), "should be", index

All this just to take advantage of the itertools.count counting :)

Post a Comment for "In Python, How Can I Find The Index Of The First Item In A List That Is Not Some Value?"