How to find the index of value in python list?

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 invert the index(x) method. I need to get the index of the first value in a list that does NOT have the value x. I would probably be able to even just use a function that returns the index of the first item with a value != None. I can think of a 'for' loop implementation with an incrementing counter variable, but I feel like I'm missing something. Is there an existing method, or a one-line Python construction that can handle this? In my program, the situation comes up when I'm handling lists returned from complex regex matches. All but one item in each list have a value of None. If I just needed the matched string, I could use a list comprehension like '[x for x in [my_list] if x is not None]', but I need the index in order to figure out which capture group in my regex actually caused the match.

  • Answer:

    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, return next((i for i, v in enumerate(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!-)

Ryan B. Lynch at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

http://docs.python.org/library/functions.html#enumerate returns an iterator that yields a tuple of the current index of the iterable as well as the item itself.

Ignacio Vazquez-Abrams

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 in enumerate(lst): ... if item: break ... else: ... print "not found" ... >>> i 3

Stephen

[i for i,x in if x != value][0] If you're not sure whether there's a non-matching item, use this instead: match = [i for i,x in if x != value] if match: 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.

Marcelo Cantos

A silly itertools-based solution:) import itertools as it, operator as op, functools as ft def index_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-equals try: ne_scanner.next() # this should be the first not equal except StopIteration: return None # or raise some exception, all items equal to item else: return counter.next() # should be the index of the not-equal item if __name__ == "__main__": import random test_data= [0]*20 print "failure", index_ne(0, test_data) index= random.randrange(len(test_data)) test_data[index]= 1 print "success:", index_ne(0, test_data), "should be", index All this just to take advantage of the itertools.count counting :)

tzot

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.