16

I was looking for an elegant (short!) way to return the first element of a list that matches a certain criteria without necessarily having to evaluate the criteria for every element of the list. Eventually I came up with:

(e for e in mylist if my_criteria(e)).next()

Is there a better way to do it?

To be more precise: There's built in python functions such as all() and any() - wouldn't it make sense to have something like first() too? For some reason I dislike the call to next() in my solution.

4 Answers4

15

How about:

next((e for e in mylist if my_criteria(e)), None)
iruvar
  • 22,736
  • 7
  • 53
  • 82
10

Nope - looks fine. I would be tempted to re-write possibly as:

from itertools import ifilter
next(ifilter(my_criteria, e))

Or at least break out the computation into a generator, and then use that:

blah = (my_function(e) for e in whatever)
next(blah) # possibly use a default value

Another approach, if you don't like next:

from itertools import islice
val, = islice(blah, 1)

That'll give you a ValueError as an exception if it's "empty"

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • 5
    For someone who is seeing this for Python 3 , `itertools.ifilter` is now simply `filter` and is available in global namespace. – xssChauhan Jul 20 '17 at 10:45
1

I propose to use

next((e for e in mylist if my_criteria(e)), None)

or

next(ifilter(my_criteria, mylist), None)
oleg
  • 4,082
  • 16
  • 16
0

with for loop

lst = [False,'a',9,3.0]
for x in lst:
    if(isinstance(x,float)):
        res = x
        break

print res
kiriloff
  • 25,609
  • 37
  • 148
  • 229