First Python list index greater than x?

Viewed 131316

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.
12 Answers
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
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).

Another one:

map(lambda x: x>.7, seq).index(True)

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.

>>> 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)
Related