Transforming lambda expression to simple function - python

I'm curious if it is possible to avoid lambda expressions in the following case.
For example using lambda expression I can simple define a function that returns a lambda exp.
def square_fun(a,b,c):
return lambda x: a*x**2 + b*x + c
After we can call it using:
f = square_fun(1,2,3)
f(1) # here x = 1
How can I get the same behaviour avoiding lambda expression?
for example, square_fun must return another function
def square_fun(a,b,c):
return f...

In python you can define a function inside another function, so the following snippet should give you the same behavior:
def square_fun(a, b, c):
def result(x):
return a*x**2 + b*x + c
return result
f = square_fun(1, 2, 3)
print(f(1))
# Should print 6
So, I'll try to explain what's going on here:
In the line f = square_fun(1, 2, 3), f will actually be mapped to the internal function (aka. result)
Please note that return result does not have the () at the end, hence the function is not called yet
The function gets called in print(f(1)) and the variable x takes 1 as its value
Finally the result function returns the computed value using x, and a, b and c (from square_fun(1, 2, 3))
You can find additional info here => https://www.learnpython.org/en/Closures

You can also use functools.partial:
from functools import partial
def square_fun(x, a, b, c):
return a * x ** 2 + b * x + c
f = partial(square_fun, a=1, b=2, c=3)
print(f(1))
# should print 6

Related

How to use one output of a function and store a second one=

So I have a function which outputs 2 values:
def example(a, b):
c = math.floor(a / b)
a = a%b
return (c, a)
I want to use this function this way:
print("text: ", c)
How can I use the function and print c, but store x for later?
Your function will return a tuple containing the two values. You can assign the result of calling your function to a variable.
Note,
that the parentheses are not required in your return statement.
you can replace math.floor(a / b) with a // b which will also do a floor division.
An example is shown below where the result of calling the function is unpacked into two variables, c and a.
def example(a, b):
c = a // b
a = a % b
return c, a
c, a = example(6, 3)
print("text:", c)
Alternatively, you can also store the result in a single variable that references your tuple as follows:
data = example(6, 3)
print("text:", data[0])
First, you need to call the function and assign its return values to some variables:
x, y = example(42, 5)
Then you can print the results:
print(x)
print(y)
You can even skip the variable assignment if you wish so
print("text:", example(a, b)[0])
but it's ugly

How do I do multiple things inside one lambda function?

I am learning Python and I want to do multiple things inside one lambda function.
Just for a small example if I want to do addition, subtraction, and multiplication in one function, how do I do that?
I tried to use code like this just to see if it would work and it didn't:
a = 1
b = 2
myFunction = lambda a, b: a + b, b - a, a * b
print(myFunction(a, b))
You can group those operations in a tuple
a = 1
b = 2
myFunction = lambda a, b: (a + b, b - a, a * b)
myFunction(a, b)
output:
(3, 1, 2)
NB. The mistake in you code is that myFunction was a tuple containing your lambda as first element, not a function.
I think there is a slight syntax issue around a lambda returning a tuple.
Use this syntax:
a = 1
b = 2
myFunction = lambda a, b: (a + b, b - a, a * b)
print(myFunction(a, b))

Function as an argument of another function

I'm learning this language hence I'm new with Python. The code is:
def add(a, b):
return a + b
def double_add(x, a, b):
return x(x(a, b), x(a, b))
a = 4
b = 5
print(double_add(add, a, b))
The add function is simple, it adds two numbers. The double_add function has three arguments. I understand what is happening (With some doubts). The result is 18. I can't understand how double_add uses add to function.
The question is, what is the connection between these two functions?
It would be helpful if tell me some examples of using a function as an argument of another function.
Thanks in advance.
In python language, functions (and methods) are first class objects. First Class objects are those objects, which can be handled uniformly.
So, you just pass a method as an argument.
Your method will return add(add(4, 5), add(4, 5)) which is add(9, 9) and it's equals to 18.
A function is an object just like any other in Python. So you can pass it as argument, assign attributes to it, and well maybe most importantely - call it. We can look at a simpler example to understand how passing a function works:
def add(a, b):
return a + b
def sub(a, b):
return a - b
def operate(func, a, b):
return func(a, b)
a = 4
b = 5
print(operate(add, a, b))
print(operate(sub, a, b))
operate(print, a, b)
And this prints out:
9
-1
4 5
That is because in each case, func is assigned with the respective function object passed as an argument, and then by doing func(a, b) it actually calls that function on the given arguments.
So what happens with your line:
return x(x(a, b), x(a, b))
is first both x(a, b) are evaluated as add(4, 5) which gives 9. And then the outer x(...) is evaluated as add(9, 9) which gives 18.
If you would add print(x) in the double_add function you would see that it would print <function add at 0x10dd12290>.
Therefore, the code of double_add is basically the same as if you would do following:
print(add(add(a,b), add(a,b))) # returns 18 in your case
Functions are objects in Python, just like anything else such as lists, strings.. and you can pass them same way you do with variables.
The function object add is passed as an argument to double_add, where it is locally referred to as x. x is then called on each, and then on the two return values from that.
def double_add(x, a, b):
return x(x(a, b), x(a, b))
Let's write it differently so it's easier to explain:
def double_add(x, a, b):
result1 = x(a, b)
result2 = x(a, b)
return x(result1, result2)
This means, take the function x, and apply it to the parameters a and b. x could be whatever function here.
print(double_add(add, a, b))
Then this means: call the double_add function, giving itaddas the first parameter. Sodouble_add`, would do:
result1 = add(a, b)
result2 = add(a, b)
return add(result1, result2)
This is a very simple example of what is called "dependency injection". What it means is that you are not explicitly defining an interaction between the two functions, instead you are defining that double_add should use some function, but it only knows what it is when the code is actually run. (At runtime you are injecting the depedency on a specific function, instead of hardcoding it in the function itself),
Try for example the following
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def double_add(x, a, b):
return x(x(a, b), x(a, b))
a = 4
b = 5
print(double_add(add, a, b))
print(double_add(subtract, a, b))
In other words, double_add has become a generic function that will execute whatever you give it twice and print the result

Function that returns a function that returns a function

I've been given this function. It returns the function pair that it also returns the function f I think. That is the part that tricks me, I don't know what f(a, b) is and how to use it.
def cons(a, b):
def pair(f):
return f(a, b)
return pair
To help you understand what is going on, consider the following example:
def cons(a, b):
def pair(f):
return f(a, b)
return pair
def my_func(a, b):
return a + b
# cons returns a function that takes a function arg and calls it with args (a, b),
# in this case (1, 3). Here a, b are considered "closured" variables.
apply_func = cons(1, 3)
print apply_func(my_func) # prints 4
Lets analyse this from inside out:
def cons(a, b):
def pair(f):
return f(a, b)
return pair
The innermost level is return f(a, b) - that obviously calls function f with arguments (a, b) and returns whatever the result of that is.
The next level is pair:
def pair(f):
return f(a, b)
Function pair takes a function as an argument, calls that function with two arguments (a, b) and returns the result. For example:
def plus(x, y):
return x + y
a = 7
b = 8
pair(plus) # returns 15
The outermost level is cons - it constructs function pair which has arbitrary a and b and returns that version of pair. E.g.
pair_2_3 = cons(2,3)
pair_2_3(plus) # returns 5, because it calls plus(2, 3)
. . . I don't know what f(a, b) is and how to use it.
f(a, b) is simply a function call. All the code you provided does is define a function that returns a function. The function returned from the first function, itself returns a function. I assume the way it would be used is perhaps something like:
>>> cons(1, 2)(lambda x, y: x + y)
3
>>>
The above code would be equivalent to:
>>> pair_func = cons(1, 2) # return the `pair` function defined in `cons`
>>> f = lambda x, y: x + y
>>> pair_func(f) # apply the `f` function to the arguments passed into `cons`.
3
>>>
It might also help to note that the pair function defined in this case, is what's know as a closure. Essentially, a closure is a function which has access to local variables from an enclosing function's scope, after the function has finished execution. In your specific case, cons is the enclosing function, pair is the closure, and a and b are the variables the closure is accessing.
Well if you could share the complete question then we might be able to help you better. Meanwhile what I can tell you here is that in the return of pair(f) the program is calling a function f which takes two arguments a and b. This function f(a,b) is called and then its value will be returned to pair(f).
But the point to note here is that in pair function we already have a local variable f, so when we will try to call the function f(a,b) it will give us UnboundedLocalVariable error. Therefore, we will need to change the name of this function from f to something else.

Convenient way to add lambda functions together?

Let's say I have this function in a python module:
def functionmaker(a,b):
return lambda x: (a*x) + b
Now let's say I am given a list of this format:
ablist = [[a1, b1], [a2, b2]...[an, bn]] of arbitrary length.
My goal is to add up all the resulting functions you get from these a's and b's.
Of course, with the simple example I gave of ax+b, you could algebraically work it out to being (a1 + a2 + ... an)x + (b1 + b2 + ... bn). But let's ignore that for a moment. The function I am actually working with is a contracted gaussian molecular orbital function, and it's not as easy to trick your way out of the problem with algebra.
What I wanted to do was something like this:
function = lambda x: (a1*x) + b1
q = 2
while q < n:
function = lambda x: function(x) + (ablist[q][0]*x) + ablist[q][1])
q += 1
But it seems you can't call a function inside itself like that. I was hoping it would just over-write the old version of "function" with the new one, but I guess not. I guess I probably need to do some kind of recursive way, but maybe there is a nicer way?
By the way I am using python 2.7.
You can do something like this:
>>> def functionmaker(a, b):
... return lambda x: a*x + b
...
>>> def summer_funcs(args):
... return lambda x: sum(functionmaker(*a)(x) for a in args)
...
>>> arguments = [(1,2), (3,4), (5,6)]
>>> summer_funcs(arguments)(1)
21
Or if you prefer:
>>> f = summer_funcs(arguments)
>>> f(1)
21
>>> f(2)
30
If I've correctly understood your question, you could use the built-in sum() function and pass it a generator expression argument to accomplish the goal:
def functionmaker(a, b):
return lambda x: (a*x) + b
ablist = [(1,2), (3,4), (5,6)]
x = 1
total = sum(functionmaker(a, b)(x) for a, b in ablist)
print(total) # -> 21
If you need to compute this quantity for many different values of x, then it might be worthwhile to optimize things for doing that:
functions = [functionmaker(a, b) for a, b in ablist]
sum_of_functions = lambda x: sum(function(x) for function in functions)
for x in (1, 1.5, 2):
print('sum_of_functions(x={:.1f}) -> {:.1f}'.format(x, sum_of_functions(x)))
Output:
sum_of_functions(x=1.0) -> 21.0
sum_of_functions(x=1.5) -> 25.5
sum_of_functions(x=2.0) -> 30.0

Categories