Alberto Castaño
Alberto Castaño

Reputation: 306

Check equality between arguments a variable inside a lambda expression

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?

Upvotes: 0

Views: 99

Answers (2)

jVincent
jVincent

Reputation: 323

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.

Upvotes: 0

Netwave
Netwave

Reputation: 42746

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)

Upvotes: 2

Related Questions