In Python, How Can I Find The Index Of The First Item In A List That Is Not Some Value?
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?"