Wrappers around lambda expressions - python

I have functions in python that take two inputs, do some manipulations, and return two outputs. I would like to rearrange the output arguments, so I wrote a wrapper function around the original function that creates a new function with the new output order
def rotate(f):
h = lambda x,y: -f(x,y)[1], f(x,y)[0]
return h
f = lambda x, y: (-y, x)
h = rotate(f)
However, this is giving an error message:
NameError: global name 'x' is not defined
x is an argument to a lambda expression, so why does it have to be defined?
The expected behavior is that h should be a new function that is identical to lambda x,y: (-x,-y)

You need to add parentheses around the lambda expression:
h = lambda x,y: (-f(x,y)[1], f(x,y)[0])
Otherwise, Python interprets the code as:
h = (lambda x,y: -f(x,y)[1]), f(x,y)[0]
and h is a 2-tuple.

There is problem with precedence. Just use additional parentheses:
def rotate(f):
h = lambda x,y: (-f(x,y)[1], f(x,y)[0])
return h

Related

How does currying lambda expressions work?

I have no clue how the code executes. This is a question on a practice test.
(lambda x: x(x))(lambda y:4)
The output is 4 but I don't know how the code runs. I think the steps are as follows:
lambda (x) is defined
executes lambda (x)
returns x(lambda(y))
lambda (y) is defined
returns 4
x(4)?
I know step 6 is wrong.
This is a tricky question.
Lambdas are anonymous functions. Let's define them to help you understand what is happening.
# (lambda x: x(x))
def func_1(func):
return func(func)
# (lambda y: 4)
def func_2(y):
return 4
>>> func_1(func_2) # Equivalent to (lambda x: x(x))(lambda y:4)
4
The second function is just a callable that returns the constant value of 4 regardless of the value of y, so func_2(10) and func_2(0) both return 4.
The first function is a callable with itself as the single argument to the function (x(x)). We just saw that the second function is a callable that will return the constant value 4 regardless of the input argument, so func_2(func_2) simply returns 4.
lambda expression works just like an unnamed function (anonymous functions). And works like this:
lambda (1): (2)
(1) are parameters
(2) the return
See:
def square(x):
return x**2
Using lambda expression:
square = lambda x: x**2
>>> square(2)
4
But think about the use, maybe you just want to use an function a few times, why store it? Create an anonymous function! How? running a lambda function:
>>> (lambda x: x**2)(2)
4
See? Not that hard. Let's think together.
(lambda x: x(x))(lambda y:4)
lambda y: 4 is passed to our lambda x function, now x = (lambda y: 4) (crazy thing!). x(x) are equals to (lambda y: 4)((lambda y: 4)). Look! We got an parameter to our first 'y' it is (lambda y: 4)! then the first function are executed, and returns 4. What about the second? It doesn't run, and don't need to run! if you do x(x(x)) the second function will run, but not the third one.
Don't think about "lambda is defined". A lambda is a value, like 4. You don't "define" a 4 - it just is. When evaluating a lambda, just replace its (evaluated) arguments into its body (adding parentheses where neccessary). Work it like a rewriting problem.
(lambda x: x(x))(lambda y:4)
# rewrite all `x` in `x(x)` to `lambda y:4` (two appearances):
(lambda y:4)(lambda y:4)
# rewrite all `y` in `4` to `lambda y:4` (zero appearances):
4

How does lambda inside lambda function work?

When I try to print and see what each function does, I'm able to call only the h function. All others return functions.
Also, can anybody tell me why this code prints 13 and what is happening?
two_to_one = lambda g: (lambda y: g(y,y))`
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
h = one_to_two(two_to_one(lambda x, y: x*y))
print(h(3,2))
That was quite a mind bender!
So let's just break the logic bit by bit. We'll start from h, it is essentially
h = lambda x, y : x*x + y*y
h(3,2) # output is 13
Now, we'll be good programmers and look for repetition. x*x and y*y are essentially the same thing. Why not have a lambda that does that?
a = lambda x: x*x
h = lambda x,y: a(x) + a(y)
h(3,2)
Good, but I want the caller to decide whether to do x*x or x**x or x+x. Everytime I do that I dont want to change a. So I instead pass a lambda to a with whatever operation I want to perform
# a is just a delegator now. It just calls the lambda that it is "initialized" with passing the values twice
a = lambda lambdaIAmPassing: (lambda someValue: lambdaIAmPassing(someValue, someValue))
# lets pass a multiplication lambda
mul_a = a(lambda x,y: x*y)
# lets pass a addition doing lambda
add_a = a(lambda x,y: x+y)
h = mul_a(3) + mul_a(2)
print h #output is 13
h = add_a(3) + add_a(2)
print h # output is 10
Is this clear? You would have realized now that a is in fact the lambda two_to_one in your question
Now the final step.Do you see any other repetition in the code? we are calling mul_a twice and add_a twice. So to avoid this we define a lambda that calls whatever function is passed to it twice - once per parameter - and adds up the values
# Lambda that adds up the result of the function call
lambda_adder = lambda f: (lambda value1, value2: f(value1) + f(value2))
"Initialize" this lambda with mul_a
h = lambda_adder(mul_a)
h(3,2) # output is 13
Hence we end up with the code in your question
two_to_one = lambda g: (lambda y: g(y,y))
This equals a function which calls a function g, passing it two variables, both y. In this case, g is
lambda x, y: x*y
because that is the argument passed to two_to_one on the third line (h's assignment).
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
This equals a function which returns the sum of two calls to the function f, passing the values x and y. In this case, f is the two_to_one function.
Breaking it down:
first = lambda x, y: x*y
second = lambda y: first(y,y)
third = lambda x, y: second(x) + second(y)
simplifies to:
second = lambda y: y * y
third = lambda x, y: second(x) + second(y)
simplifies to:
third = lambda x, y: x * x + y * y
So, what the code is doing is returning the sum of the squares of the arguments. In this case, they are 3 and 2.
I hope it will be relatively easy to follow.
two_to_one = lambda g: (lambda y: g(y,y))
two_to_one is a function, with an input of a function (g: a function with an input of two parameters (as seen in g(y,y)), and output of a function (with 1 input y, and output of g(y,y)). Meaning it is a function of functions. So when giving two_to_one a two parameter function g, you get back a function, that takes 1 number and outputs g(y,y).
e.g:
two_to_one(lambda x,y:x+y)(3)
6
We gave two_to_one a function that gets two numbers and output their sum, lambda x,y:x+y, and we got back a function that takes 1 number and output its sum with itself two_to_one(lambda x,y:x+y). So with an input of 3 it outputs 6.
Second line is similiar:
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
Take a function f (of 1 parameter - due to f(x)), and give back a function, that gets two parameters (numbers probably) x,y and outputs f(x) + f(y).
Now, for the 13 output - working from inner to outer:
h = one_to_two(two_to_one(lambda x, y: x*y))
lambda x, y: x*y two parameter input - output of multiplication. This is the input of two_to_one so (remember what was written earlier) two_to_one(lambda x, y: x*y) is a function that gets 1 number, and returns it squared. And finally, feeding this function to one_to_two gives a function that gets two numbers (those x,y frim before) and returns their sum of squares.
In total h(3,2) gives 3**2+2**2=13.

function making

Hi I am new to functional programming. What i did is
>>> g=lambda x:x*2
>>> f=g
>>> g=lambda x:f(f(x))
>>> g(9)
36
Now, it is not creating g as a nonterminating recursive function - g(x) is transformed to a new function which gives the result g(g(x)).
>>> f=g
>>> g=lambda x:f(f(x))
>>> f(8)
RuntimeError: maximum recursion depth exceeded
I expected g to be transformed into a function which gives the result g(g(g(x))), according to the first definition of g(x). Why does it not? Is it possible to make a new function which results in g(g(g(...(g(x))....))) for a certain number of iterations in this way?
When you do f = g for the second time, f becomes lambda x: f(x). Closures are created by name, not by value.
This becomes easy with a helper function:
def compose(f, g):
return lambda x: f(g(x))
square = lambda x:x*2
g = square
for i in xrange(4):
g = compose(g, square)
In python, variables are names mapped to values, not values themselves (everything is a reference). Also, you can think of lambda as storing text that can be evaluated. The following will illustrate
a = 2
f = lambda x: a*x
f(2) # This gives 4
a = 3
f(2) # This gives 6
This should clear up why you are getting infinite recursion.
In answer to your question about recursing, here is a little hack that might do
g = lambda x, n: n > 0 and g(x, n-1)**2 or x
Then g(2,3) would be (((2)^2)^2)^2 = 256.
This
g=lambda x:x*2
f=g
g=lambda x:f(x)
is equivalent to:
f=lambda x:x*2
g=lambda x:f(x)
When you call g, you get whatever f happens to be defined in the global (or enclosing) scope.
what you're expecting is something like:
f=lambda x:x*2
g=lambda x, f=f:f(x)
That captures the value of f in the outer scope at the time the lambda expression is evaluated.

lambda returns lambda in python

Very rarely I'll come across some code in python that uses an anonymous function which returns an anonymous function...?
Unfortunately I can't find an example on hand, but it usually takes the form like this:
g = lambda x,c: x**c lambda c: c+1
Why would someone do this? Maybe you can give an example that makes sense (I'm not sure the one I made makes any sense).
Edit: Here's an example:
swap = lambda a,x,y:(lambda f=a.__setitem__:(f(x,(a[x],a[y])),
f(y,a[x][0]),f(x,a[x][1])))()
You could use such a construct to do currying:
curry = lambda f, a: lambda x: f(a, x)
You might use it like:
>>> add = lambda x, y: x + y
>>> add5 = curry(add, 5)
>>> add5(3)
8
swap = lambda a,x,y:(lambda f=a.__setitem__:(f(x,(a[x],a[y])),
f(y,a[x][0]),f(x,a[x][1])))()
See the () at the end? The inner lambda isn't returned, its called.
The function does the equivalent of
def swap(a, x, y):
a[x] = (a[x], a[y])
a[y] = a[x][0]
a[x] = a[x][1]
But let's suppose that we want to do this in a lambda. We cannot use assignments in a lambda. However, we can call __setitem__ for the same effect.
def swap(a, x, y):
a.__setitem__(x, (a[x], a[y]))
a.__setitem__(y, a[x][0])
a.__setitem__(x, a[x][1])
But for a lambda, we can only have one expression. But since these are function calls we can wrap them up in a tuple
def swap(a, x, y):
(a.__setitem__(x, (a[x], a[y])),
a.__setitem__(y, a[x][0]),
a.__setitem__(x, a[x][1]))
However, all those __setitem__'s are getting me down, so let's factor them out:
def swap(a, x, y):
f = a.__setitem__
(f(x, (a[x], a[y])),
f(y, a[x][0]),
f(x, a[x][1]))
Dagnamit, I can't get away with adding another assignment! I know let's abuse default parameters.
def swap(a, x, y):
def inner(f = a.__setitem__):
(f(x, (a[x], a[y])),
f(y, a[x][0]),
f(x, a[x][1]))
inner()
Ok let's switch over to lambdas:
swap = lambda a, x, y: lambda f = a.__setitem__: (f(x, (a[x], a[y])), f(y, a[x][0]), f(x, a[x][1]))()
Which brings us back to the original expression (plus/minus typos)
All of this leads back to the question: Why?
The function should have been implemented as
def swap(a, x, y):
a[x],a[y] = a[y],a[x]
The original author went way out of his way to use a lambda rather then a function. It could be that he doesn't like nested function for some reason. I don't know. All I'll say is its bad code. (unless there is a mysterious justification for it.)
It can be useful for temporary placeholders. Suppose you have a decorator factory:
#call_logger(log_arguments=True, log_return=False)
def f(a, b):
pass
You can temporarily replace it with
call_logger = lambda *a, **kw: lambda f: f
It can also be useful if it indirectly returns a lambda:
import collections
collections.defaultdict(lambda: collections.defaultdict(lambda: collections.defaultdict(int)))
It's also useful for creating callable factories in the Python console.
And just because something is possible doesn't mean that you have to use it.
I did something like this just the other day to disable a test method in a unittest suite.
disable = lambda fn : lambda *args, **kwargs: None
#disable
test_method(self):
... test code that I wanted to disable ...
Easy to re-enable it later.
This can be used to pull out some common repetitive code (there are of course other ways to achieve this in python).
Maybe you're writing a a logger, and you need to prepend the level to the log string. You might write something like:
import sys
prefixer = lambda prefix: lambda message: sys.stderr.write(prefix + ":" + message + "\n")
log_error = prefixer("ERROR")
log_warning = prefixer("WARNING")
log_info = prefixer("INFO")
log_debug = prefixer("DEBUG")
log_info("An informative message")
log_error("Oh no, a fatal problem")
This program prints out
INFO:An informative message
ERROR:Oh no, a fatal problem
It is most oftenly - at least in code I come accross and that I myself write - used to "freeze" a variable with the value it has at the point the lambda function is created. Otherwise, nonlocals variable reference a variable in the scope they exist, which can lead to undesied results sometimes.
For example, if I want to create a list of ten functions, each one being a multiplier for a scalar from 0 to 9. One might be tempted to write it like this:
>>> a = [(lambda j: i * j) for i in range(10)]
>>> a[9](10)
90
Whoever, if you want to use any of the other factoried functions you get the same result:
>>> a[1](10)
90
That is because the "i" variable inside the lambda is not resolved when the lambda is created. Rather, Python keeps a reference to the "i" in the "for" statement - on the scope it was created (this reference is kept in the lambda function closure). When the lambda is executed, the variable is evaluated, and its value is the final one it had in that scope.
When one uses two nested lambdas like this:
>>> a = [(lambda k: (lambda j: k * j))(i) for i in range(10)]
The "i" variable is evaluated durint the execution of the "for" loop. ItÅ› value is passed to "k" - and "k" is used as the non-local variable in the multiplier function we are factoring out. For each value of i, there will be a different instance of the enclosing lambda function, and a different value for the "k" variable.
So, it is possible to achieve the original intent :
>>> a = [(lambda k: (lambda j: k * j))(i) for i in range(10)]
>>> a[1](10)
10
>>> a[9](10)
90
>>>
It can be used to achieve a more continuation/trampolining style of programming,
See Continuation-passing style
Basically, with this you can modify functions instead of values
One example I stumbled with recently: To compute approximate derivatives (as functions) and use it as an input function in another place.
dx = 1/10**6
ddx = lambda f: lambda x: (f(x + dx) - f(x))/dx
f = lambda x: foo(x)
newton_method(func=ddx(f), x0=1, n=10)

recursive lambda-expressions possible?

I'm trying to write a lambda-expression that calls itself, but i can't seem to find any syntax for that, or even if it's possible.
Essentially what I wanted to transfer the following function into the following lambda expression: (I realize it's a silly application, it just adds, but I'm exploring what I can do with lambda-expressions in python)
def add(a, b):
if a <= 0:
return b
else:
return 1 + add(a - 1, b)
add = lambda a, b: [1 + add(a-1, b), b][a <= 0]
but calling the lambda form of add results in a runtime error because the maximum recursion depth is reached. Is it even possible to do this in python? Or am I just making some stupid mistake? Oh, I'm using python3.0, but I don't think that should matter?
Maybe you need a Y combinator?
Edit - make that a Z combinator (I hadn't realized that Y combinators are more for call-by-name)
Using the definition of the Z combinator from Wikipedia
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
Using this, you can then define add as a completely anonymous function (ie. no reference to its name in its definition)
>>> add = Z(lambda f: lambda a, b: b if a <= 0 else 1 + f(a - 1, b))
>>> add(1, 1)
2
>>> add(1, 5)
6
Perhaps you should try the Z combinator, where this example is from:
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
>>> fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
>>> Z(fact)(5)
120
First of all recursive lambda expressions are completely unnecessary. As you yourself point out, for the lambda expression to call itself, it needs to have a name. But lambda expressions is nothing else than anonymous functions. So if you give the lambda expression a name, it's no longer a lambda expression, but a function.
Hence, using a lambda expression is useless, and will only confuse people. So create it with a def instead.
But yes, as you yourself discovered, lambda expressions can be recursive. Your own example is. It's in fact so fantastically recursive that you exceed the maximum recursion depth. So it's recursive alright. Your problem is that you always call add in the expression, so the recursion never stops. Don't do that. Your expression can be expressed like this instead:
add = lambda a, b: a > 0 and (1 + add(a-1, b)) or b
Which takes care of that problem. However, your first def is the correct way of doing it.
add = lambda a, b: b if a <= 0 else 1 + add(a - 1, b)
You want the Y combinator, or some other fixed point combinator.
Here's an example implementation as a Python lambda expression:
Y = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))
Use it like so:
factorial = Y(lambda f: (lambda num: num and num * f(num - 1) or 1))
That is, you pass into Y() a single-argument function (or lambda), which receives as its argument a recursive version of itself. So the function doesn't need to know its own name, since it gets a reference to itself instead.
Note that this does get tricky for your add() function because the Y combinator only supports passing a single argument. You can get more arguments by currying -- but I'll leave that as an exercise for the reader. :-)
a little late ... but I just found this gem # http://metapython.blogspot.com/2010/11/recursive-lambda-functions.html
def myself (*args, **kw):
caller_frame = currentframe(1)
code = caller_frame.f_code
return FunctionType(code, caller_frame.f_globals)(*args,**kw)
print "5! = "
print (lambda x:1 if n <= 1 else myself(n-1)*n)(5)

Categories