If I state a lambda function like this:
someLambdaFunction = lambda x,y: x+x**2+y
can I reverse the ordering of that lambda to say
someOtherLambdaFunction = lambda y,x: x+x**2+y
without rewriting the whole lambda function? Just switch the arguments?
Yes, you can do something like this:
someLambdaFunction = lambda x,y: x+x**2+y
someOtherLambdaFunction = lambda y, x: someLambdaFunction(x, y)
Basically, reuse the original someLambdaFunction
You can write a general function that swaps the first two arguments of another function:
def swap2(func):
""" Swap the first two arguments of a function """
def wrapped(x, y, *args, **kwargs):
return func(y, x, *args, **kwargs)
return wrapped
f = lambda x,y: x+x**2+y
f_swapped= swap2(f)
assert f(3, 4) == f_swapped(4, 3)
This works because functions are just regular Python objects, that can be passed around just like integers, strings, etc.
By the way, there is almost never a reason to write something = lambda .... Use def something(...) instead.
Related
Can someone please explain to me how this nested lambdas + decorator work and what is the chronical
logic behind the output:
amp = lambda f: lambda g:lambda x:g(f(f(x)))
my_dec=amp(lambda x: "*"+x+"*")
#my_dec
def my_print(y):
print(y)
my_print("hello")
That's a tricky one:
amp is a function that takes another function f as parameter and return another funktion g taking a function x as parameter
you call amp with lambda x: "*"+x+"*", which is applied twice to the argument of the "innermost" function before passing it to the "middle" function; the result of that is your decorator my_dec
that decorator is then applied to the my_print function, making my_print the g parameter in the lambda g: ... returned by amp
finally, you pass "hello" to that decorated function, which is routed through f i.e. lambda x: "*"+x+"*" before being passed to g i.e. my_print
The whole thing becomes much clearer if you use proper def functions and longer parameter names (keeping the original g, f, and x for reference):
def amp(f_preproc):
def my_parameterized_dec(g_function):
def decorated_function(x_original_arg):
new_arg = f_preproc(f_preproc(x_original_arg))
return g_function(new_arg)
return decorated_function
return my_parameterized_dec
#amp(lambda x: "*"+x+"*")
def my_print(y):
print(y)
The two ways I'm aware of to have a partially-bound function that can be later called is:
apply_twice = lambda f: lambda x: f(f(x))
square2x = apply_twice(lambda x: x*x)
square2x(2)
# 16
And
def apply_twice(f):
def apply(x):
return f(f(x))
return apply
square_2x=apply_twice(lambda x: x*x)
square_2x(4)
# 256
Are there any other common ways to pass around or use partially-bound functions?
functools.partial can be used to partially apply an ordinary Python function. This is especially useful if you already have a regular function and want to apply only some of the arguments.
from functools import partial
def apply_twice(f, x):
return f(f(x))
square2x = partial(apply_twice, lambda x: x*x)
print(square2x(4))
It's also important to remember that functions are only one type of callable in Python, and we're free to define callables ourselves as ordinary user-defined classes. So if you have some complex operation that you want to behave like a function, you can always write a class, which lets you document in more detail what it is and what the different parts mean.
class MyApplyTwice:
def __init__(self, f):
self.f = f
def __call__(self, x):
return self.f(self.f(x))
square2x = MyApplyTwice(lambda x: x*x)
print(square2x(4))
While overly verbose in this example, it can be helpful to write your function out as a class if it's going to be storing state long-term or might be doing confusing mutable things with its state. It's also useful to keep in mind for learning purposes, as it's a healthy reminder that closures and objects are two sides of the same coin. They're really the same thing, viewed in a different light.
You can also do this with functools.partial():
def apply_twice(f, x):
return f(f(x))
square_2x = functools.partial(apply_twice, lambda x: x*x)
This isn't really partial binding, assuming you mean partial application.
Partial application is when you create a function that does the same thing as another function by fixing some number of its arguments, producing a function of smaller arity (the arity of a function is the number of arugments it takes).
So, for example,
def foo(a, b, c):
return a + b + c
A partially applied version of foo would be something like:
def partial_foo(a, b):
return foo(a, b, 42)
Or, with a lambda expression:
partial_foo = lambda a, b: foo(a, b, 42)
However, note, the above goes against the official style guidelines, in PEP8, you shouldn't assign the result of lambda expressions to a name, if you are going to do that just use a full function defintion.
The module, functools, has a helper for partial application:
import functools
partial_foo = functools.partial(foo, c=42)
Note, you may have heard about "currying", which sometimes gets confused for partial application. Currying is when you decompose a n-arity function into N, 1-arity functions. So, more concretely, for foo:
curried_foo = lambda a: lambda b: lambda c: a + b + c
Or in long form:
def curried_foo(a):
def _curr0(b):
def _curr1(c):
return a + b + c
return _curr1
return _curr0
And the important part, curried_foo(1)(2)(3) == foo(1, 2, 3)
If I have a function that takes in a lambda reference as a parameter, and returns that reference so when it's called, it returns the value of that lambda function (boolean).
Is there a way to have it return the opposite boolean value?
def returns_diff(lambda_function):
return lambda_function
f = returns_diff(lambda x : x > 2)
f(0)
# I know I can do it this way but I want to do it inside the function.
# print(not(f(0)))
---> Should return True because it's supposed to return False since 0 is not bigger than two (return the opposite value of the lambda function)
I know I can just do: not(f(0)) when calling it, but I want to do it inside the function, not when I call it.
If you want to generate a function that returns the boolean opposite of a given function, you can do it like this:
def returns_diff(func):
return lambda x: not func(x)
f = returns_diff(lambda x: x>2)
f(0) # returns True
That's assuming the functions take one argument, as in your question. You can also make a version that works for functions with any number of positional or keyword arguments:
def returns_diff(func):
return lambda *args, **kwargs: not func(*args, **kwargs)
Can i use classes? Or it need to be just plain functions? With classes i would do
class diff:
def __init__(self,lambda_func):
self.lambda_func = lambda_func
def __call__(self,x):
return not(self.lambda_func(x))
f = diff(lambda x: x > 2)
f(0) #True
I'm going through some interview prep questions a college advisor gave me and this question was suggested as being prepared for different interviews:
"Complete the function:
applyFunctions(outer_function, inner_function)
which takes two functions, an outer and an inner, and returns a function which applies the outer function to the inner function to an argument."
I'm somewhat puzzled by this question, given that it does not accept the argument in the function, but instead is applied outside of it:
applyFunctions(outer_function, inner_function)(5)
I am familiar with lambda and its uses, but this question has stumped me.
Any suggestions would be great. Thank you in advance.
EDIT:
A test case (example) included is:
add2 = lambda x: x + 2
times2 = lambda x: x * 2
compose(add2,times2)(3)
> 8
First define what inner and outer are: functions that take an argument and return a result.
Then define apply, a function that takes two functions, and returns a function that combines the two in some manner.
def inner(n):
print("inner called")
return 3 * n
def outer(n):
print("outer called")
return n - 5
def apply(inn, out):
return lambda n: out(inn(n))
a = apply(inner, outer)
print(a(5))
output:
10
What they mean is: make a function that, given f and g, makes a function that takes x and gives f(g(x)). A function that takes f and g looks like lambda f,g:<something> A function that takes x is lambda x:<something>. Putting it together, you have lambda f, g: lambda x: f(g(x)).
Use lambda to create a new function that passes all of *args and **kwargs to inner_function, which returns to outer_function:
def applyFunctions(outer_function, inner_function):
return lambda *args, **kwargs: outer_function(inner_function(*args, **kwargs))
I want to pass a Python function to another function with some of its parameters "filled out" ahead of time.
This is simplification what I am doing:
def add(x, y):
return x + y
def increment_factory(i): # create a function that increments by i
return (lambda y: add(i, y))
inc2 = increment_factory(2)
print inc2(3) # prints 5
I don't want to use some sort of passing of args and later exploding it with *args because the function I am passing inc2 into doesn't know to pass args to it.
This feels a bit too clever for a group project... is there a more straightforward or pythonic way to do this?
Thanks!
This is called currying, or partial application. You can use the built-in functools.partial(). Something like the following would do what you want.
import functools
def add(x,y):
return x + y
inc2 = functools.partial(add, 2)
print inc2(3)
You could also accomplish the same with a lambda function:
inc2 = lambda y: add(2, y)
print inc2(3)