0

I'm trying to store a bunch of lambda expression of the form:

for i in xrange(5):
    for j in xrange(i, 5):
        diff = abs(j - i)
        lambda a, b: abs(a, b) != diff

inside a loop. In every iteration of the loop, the value of diff changes. When it changes, the lambda expression changes as well. I want to keep the formula at it is. I have tried the following:

lambda a, b: abs(a,b) != copy.deepcopy(diff)

but it is not working.

Any idea of how can I achieve this?

5
  • 1
    What do you mean by it's not working ? Do you have an error ? an output and an expected output ? Commented Feb 27, 2017 at 9:04
  • you are not storing lambda expressions anywhere. And why are you comparing it with diff ? Commented Feb 27, 2017 at 9:08
  • 2
    Why a deepcopy of an integer? Commented Feb 27, 2017 at 9:12
  • Possible duplicate of Creating lambda inside a loop Commented Feb 27, 2017 at 9:19
  • You are encountering the phenomenon of late-binding closures. Commented Feb 27, 2017 at 9:20

2 Answers 2

2

Use partial:

from functools import partial
def foo(a,b,d):
    return abs(a,b) != d

toStore = []
for i in xrange(5):
    for j in xrange(i, 5):
        diff = abs(j - i)
        toStore.append(partial(foo, d=diff))

Partial binds functions arguments, each time you are building a partial object, which is callable, that will behave as the function with the arguments fixed to the partialed applied values.

If you want to call them later you can like for example:

toStore[0](5, 5)
Sign up to request clarification or add additional context in comments.

2 Comments

You can also use the default-argument trick to force early binding.
Thank you, you made my day :)
0

Daniel Sanches's answer is a nice way to do this. An alternate way to ensure that the lambda uses the current value of the variable, and not whatever value the variable has when it is later called is to pass the value as the default value of an argument:

So this doesn't work:

diff = abs(5-7)
tester = lambda a, b: abs(a-b) != diff
print(tester(5, 5+3))
diff = abs(5-8)
print(tester(5, 5+3))

Since it returns True and then False. But if we do it like this:

diff = abs(5-7)
tester = lambda a, b, diff=diff: abs(a-b) != diff
print(tester(5,5+3))
diff = abs(5-8)
print(tester(5,5+3))

We get True and True, since changing the value of the diff variable will not change the default value of the diff parameter in the lambda.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.