# Find the first element that meets the condition

Discussion in 'Python' started by jm.suresh@no.spam.gmail.com, Feb 25, 2007.

1. ### Guest

Hi,
I have a list and I want to find the first element that meets a
condition. I do not want to use 'filter', because I want to come out
of the iteration as soon as the first element is found.
I have implemented it this way, may be, there should be a built in
hiding somewhere in the standard libraries?

def exists(iterable, condition):
'''
Return the first element in iterble that meets the condition.
'''
for x in iterable:
if condition(x):
return x
raise Exception('No element meets the given condition.')

>>> exists(xrange(1000), lambda x: x>13)

14

-
Suresh

, Feb 25, 2007

2. ### Troy MelhaseGuest

> I have implemented it this way, may be, there should be a built in
> hiding somewhere in the standard libraries?

the itertools module might have what you're after. something similar

>>> import itertools
>>> r = iter(range(100))
>>> n = itertools.dropwhile(lambda x:x<=13, r)
>>> n.next()

14

Troy Melhase, Feb 25, 2007

3. ### Peter OttenGuest

wrote:

> I have a list and I want to find the first element that meets a
> condition. I do not want to use 'filter', because I want to come out
> of the iteration as soon as the first element is found.
> I have implemented it this way, may be, there should be a built in
> hiding somewhere in the standard libraries?
>
> def exists(iterable, condition):
> '''
> Return the first element in iterble that meets the condition.
> '''
> for x in iterable:
> if condition(x):
> return x
> raise Exception('No element meets the given condition.')
>
>
>
>>>> exists(xrange(1000), lambda x: x>13)

> 14

If you are only interested in existence you can use any() (new in Python2.5)

>>> any(x>13 for x in xrange(1000))

True

Otherwise there is itertools.ifilter() a lazy variant of the filter()
builtin:

>>> import itertools
>>> items = iter(xrange(1000)) # just to prove...
>>> itertools.ifilter(lambda x: x > 13, items).next()

14
>>> items.next() # that ifilter has consumed only the first 15 items

15

You may want to wrap the ifilter() call to get a more sensible exception,

# untested
def findfirst(items, predicate=bool):
for item in itertools.ifilter(predicate, items):
return item
raise ValueError("No matching element")

Peter

Peter Otten, Feb 25, 2007
4. ### Paul RubinGuest

"" <> writes:
> I have a list and I want to find the first element that meets a
> condition. I do not want to use 'filter', because I want to come out
> of the iteration as soon as the first element is found.
> I have implemented it this way, may be, there should be a built in
> hiding somewhere in the standard libraries?
>
> def exists(iterable, condition):

To check for existence, use any(condition, iterable). If you actually
want the first element, use itertools.ifilter(condition, iterable).next().
The suggestion of using dropwhile isn't so great because it actually
consumes the first match, so you have to write your condition to
stop immediately before the element you want, not always easy.

Paul Rubin, Feb 25, 2007