views:

128

answers:

4

In python I have the following function:

def is_a_nice_element(element, parameter):
    #do something
    return True or False

Now I would like to filter a list with this function as predicate, giving a fixed parameter. Python has the itertools.ifilter function, but I can't figure out how to pass the parameter. Is this possible? If not, how can I solve this problem?

A: 

Wrap it in a lambda:

itertools.ifilter(lambda e: is_a_nice_element(e, 42), iterable)

42 is your extra argument, or whatever else you want it to be.

Eli Bendersky
Thanks, this was what I needed indeed!
Peter Smit
A: 

If you are using ifilter then parameter would need to be constant in which case you could use a default argument parameter=something. If you want parameter to vary, you'd need to use another method to take a dyadic predicate.

If you already have the list in hand, ifilter is a bit of overkill relative to the built-in filter.

Describing what you want to accomplish would help in making a more concrete answer.

msw
Sorry, but I need this parameter to be given there. If I wouldn't need the parameter there I wouldn't have a problem.
Peter Smit
+1  A: 

I like functools.partial much better than lambda.

itertools.ifilter( partial(is_a_nice_element, parameter=X), iterable )
THC4k
+1  A: 

The solutions use lambda and functools.partial are quite correct and directly answer your question, but I don't think they are really the ideal solution.

Using filter/itertools.ifilter/map/itertools.imap with an anonymous function is prettymuch always going to be less clear than using a generator expression or list comprehension. For example, in this case I would write the generator expression

(item for item in iterable if is_a_nice_element(item, constant))

instead of using ifilter. In this case the ifilter solution is still fairly readable, but in many cases trying to go through lots of trouble to define just the right function is not going to be as worth while as just performing the operation.

Mike Graham
A disadvantage of doing it this way is that you can't parametrize the filter. EG if you want to do this filtering within a function like `def find_nice_elements(filter_function=partial(is_nice, p=42)): ...`
intuited