views:

106

answers:

3

I need a function, which is capable of iterating over the collection, calling a supplied function with element of the collection as a parameter and returning the parameter or it's index when received "True" from supplied function.

It is somethong like this:

def find(f, seq, index_only=True, item_only=False):
     """Return first item in sequence where f(item) == True."""
     index = 0
     for item in seq:
         if f(item):
             if index_only:
                 return index
             if item_only:
                 return item
             return index, item
         index+= 1
     raise KeyError

So I am wondering whether there's anything like that in standart python toolset?

+1  A: 

You can use itertools.dropwhile to skip over the items for which the supplied function returns False, then take the first item of the rest (if any). If you need the index rather than the item, incorporate enumerate from the Recipes section of itertools docs.

To reverse truth values returned by the supplied function, use a lambda (lambda x: not pred (x), where pred is the supplied function) or a named wrapper:

def negate(f):
    def wrapped(x):
        return not f(x)
    return wrapped

Example:

def odd(x): return x % 2 == 1
itertools.dropwhile(negate(odd), [2,4,1]).next()
# => 1

This will throw StopIteration if no matching item is found; wrap it in a function of your own to throw an exception of your choice instead.

Michał Marczyk
:( I think OP's question is itself the answer, this may be bit more for simple iteration.
Anurag Uniyal
I agree with Anurag, but if `itertools` were used I think `ifilter` would be simpler. Ex: `itertools.ifilter(odd, [2,4,1]).next()`
tgray
I'm inclined to agree about the `ifilter`. Also, the OP's snippet does indeed solve the basic problem just fine; still, wondering what's there in the standard lib to help avoid writing code for stuff like this seems pretty reasonable. I'd say mjv's comment on the question sums up the important lesson here perfectly.
Michał Marczyk
+3  A: 

Try itertools and for example ifilter.

gruszczy
+2  A: 

I don't think there is any such function with such exact semantics, and anyway your function is short , good enough and you can easily improve it for later use, so use it.

because simple is better than complex.

Anurag Uniyal