Last active
June 9, 2020 19:58
-
-
Save golgor/3f4a2131e67dfd6656c6e53ac14d437d to your computer and use it in GitHub Desktop.
A way to create lambda functions in a loop without having problem with shared free variables.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Returns a function with n preset when the function handle is created! | |
def adder(n): | |
def inner(x): | |
return x + n | |
return inner | |
# Creating preloaded functions | |
add_1 = adder(1) | |
add_100 = adder(100) | |
print(add_1(10)) # 1 + 10 = 11 | |
print(add_100(5)) # 100 + 5 = 105 | |
# Nesting even more! | |
def subber(n): | |
def inner(x): | |
def inner_2(y): | |
return y*x-n | |
return inner_2 | |
return inner | |
# Value to subtract. fn is a closure containting the function inner with value n assigned. | |
fn = subber(1) | |
print(f"Free variables of fn: {fn.__code__.co_freevars}") | |
# with fn as return of subber, i.e. inner, fn returns inner_2. Value to multiply with. | |
fn2 = fn(2) | |
print(f"Free variables of fn2: {fn2.__code__.co_freevars}") | |
# fn2 is called with parameter = 3, which gives 3*2-1 = 5 | |
print(f"Inner_2 returns: {fn2(3)}") | |
# Hack to go around shared free variables. y=n forces Python to | |
# evaluate n at creation time for the lambda and store it. Not | |
# referencing it when the function runs. | |
adders = [] | |
for n in range(1, 4): | |
adders.append(lambda x, y=n: x + y) | |
print(adders[0](10)) # 10 + 1 = 11 | |
print(adders[2](10)) # 10 + 3 = 13 | |
# As y is another parameter, it can be set as well... | |
print(adders[2](10, 10)) # 10 + 10 = 20 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment