0

I'd like to construct filters depending on certain parameters, by chaining together python lambdas like this:

filter_even = True
my_filter = lambda x: x # Base filter
if filter_even:
    my_filter = lambda x: my_filter(x) and x % 2 == 0
list(filter(my_filter, [1,2,3,4]))

But my_filter is not bound in the lambda, but a reference to the new lambda, so I get

RecursionError: maximum recursion depth exceeded

What is the best way to bind the old lambda inside the new one? I thought lambdas behave like variables, but in this case it seems to reference the old lambda by name instead of the content of the variable (which is replaced with the new lambda afterward)

allo
  • 3,955
  • 8
  • 40
  • 71
  • 2
    Variables in the lambda body are evaluated when the lambda is called, not when it's defined. – Barmar Sep 30 '21 at 15:59
  • 1
    Usual way is `my_filter = lambda x, my_filter=my_filter: my_filter(x) and... ` – Michael Butscher Sep 30 '21 at 15:59
  • Looks like same culprit as https://stackoverflow.com/questions/2731111/ [closures - Python lambda's binding to local values - Stack Overflow](https://stackoverflow.com/questions/10452770/) , not too sure (or [How do I create a list of Python lambdas (in a list comprehension/for loop)? - Stack Overflow](https://stackoverflow.com/questions/452610/how-do-i-create-a-list-of-python-lambdas-in-a-list-comprehension-for-loop) or [python - What do (lambda) function closures capture? - Stack Overflow](https://stackoverflow.com/questions/2295290/) ?) but the use case is quite different – user202729 Sep 30 '21 at 16:00
  • 1
    *Everything* in the body of a `lambda` is looked up by name, at the point in time when the `lambda` is actually called. The usual idiom for binding a name at the time of definition is to use a parameter (that *won't* be provided when the function is called) with a default value - `lambda x, myfilter=myfilter: ...` for example. – jasonharper Sep 30 '21 at 16:01
  • I don't see the point of this `if` since `filter_even` is never `False`. – candied_orange Sep 30 '21 at 16:08
  • 1
    @candied_orange The point is having a minimal example where appending to a lambda makes sense. – allo Sep 30 '21 at 17:00

0 Answers0