What would be the most Pythonic way to find the first index in a list that is greater than x?
For example, with
list = [0.5, 0.3, 0.9, 0.8]
The function
f(list, 0.7)
would return
2.
What would be the most Pythonic way to find the first index in a list that is greater than x?
For example, with
list = [0.5, 0.3, 0.9, 0.8]
The function
f(list, 0.7)
would return
2.
next(x[0] for x in enumerate(L) if x[1] > 0.7)
if list is sorted then bisect.bisect_left(alist, value) is faster for a large list than next(i for i, x in enumerate(alist) if x >= value).
>>> alist= [0.5, 0.3, 0.9, 0.8]
>>> [ n for n,i in enumerate(alist) if i>0.7 ][0]
2
filter(lambda x: x>.7, seq)[0]
for index, elem in enumerate(elements):
if elem > reference:
return index
raise ValueError("Nothing Found")
1) NUMPY ARGWHERE, general lists
If you are happy to use numpy (imported as np here), then the following will work on general lists (sorted or unsorted):
np.argwhere(np.array(searchlist)>x)[0]
or if you need the answer as a integer index:
np.argwhere(np.array(searchlist)>x)[0][0]
2) NUMPY SEARCHSORTED, sorted lists (very efficient for searching lists within a list)
However, if your search list [l1,l2,...] is sorted, it is much cleaner and nicer to use the function np.searchsorted:
np.searchsorted(searchlist,x)
The nice thing about using this function is that as well as searching for a single value x within the search list [l1,l2,...], you can also search for a list of values [x1,x2,x3...xn] within your search list (i.e. x can be a list too, and it is extremely efficient relative to a list comprehension in this case).
I know there are already plenty of answers, but I sometimes I feel that the word pythonic is translated into 'one-liner'.
When I think a better definition is closer to this answer:
"Exploiting the features of the Python language to produce code that is clear, concise and maintainable."
While some of the above answers are concise, I do not find them to be clear and it would take a newbie programmer a while to understand, therefore not making them extremely maintainable for a team built of many skill levels.
l = [0.5, 0.3, 0.9, 0.8]
def f(l, x):
for i in l:
if i >x: break
return l.index(i)
f(l,.7)
or
l = [0.5, 0.3, 0.9, 0.8]
def f(l, x):
for i in l:
if i >x: return l.index(i)
f(l,.7)
I think the above is easily understood by a newbie and is still concise enough to be accepted by any veteran python programmer.
I think writing dumb code is a positive.
I had similar problem when my list was very long. comprehension or filter -based solutions would go thru whole list. itertools.takewhile will break the loop once condition become false first time:
from itertools import takewhile
def f(l, b): return len([x for x in takewhile(lambda x: x[1] <= b, enumerate(l))])
l = [0.5, 0.3, 0.9, 0.8]
f(l, 0.7)
>>> f=lambda seq, m: [ii for ii in xrange(0, len(seq)) if seq[ii] > m][0]
>>> f([.5, .3, .9, .8], 0.7)
2
You could also do this using numpy:
import numpy as np
list(np.array(SearchList) > x).index(True)
Try this one:
def Renumerate(l):
return [(len(l) - x, y) for x,y in enumerate(l)]
example code:
Renumerate(range(10))
output:
(10, 0)
(9, 1)
(8, 2)
(7, 3)
(6, 4)
(5, 5)
(4, 6)
(3, 7)
(2, 8)
(1, 9)