What is the logic behind this example? - python

def myfunc(n):
return lambda a : a * n
mytripler = myfunc(3)
print(mytripler(11))
I am trying to learn about the lambda function in python. I understand the other examples given inside w3schools about the Lambda function. This example, however, I could not wrap my head around. How is it that mytripler(11) multiplies 3 by 11?

Note that there is nothing particularly special about lambda. It's just a convenient method of creating an anonymous function.
If the code had instead been written:
def myfunc(n):
def inner(a):
return a * n
return inner
It would be the exact same thing. Except now we've given anonymous function a name inner. But you'd discover that you can still write mytripler = myfunc(3) and it works the same way.
Python understands closures. If a variable is used (but not modified) inside an inner function, and there is an identically named variable defined in a containing function, then Python realizes that the inner variable refers to whatever value that outer variable has.

Let's take a step back: What is a function?
One definition could be that's a construct where you give it arguments, it does something and it returns a value (Let's ignore for now the cases where you don't give any arguments or where you don't receive any return value)
In Python, since everything is an object, this kind of construct is a value that can be assigned a name. For example:
>>> def example_function(argument):
... result = argument * 42
... return result
...
>>> other_name_for_example_function = example_function
>>> example_function(3)
126
>>> other_name_for_example_function(3)
126
>>> example_function == other_name_for_example_function
True
>>> example_function is other_name_for_example_function
True
Note that in the comparison made at the end, I do not call these functions, I just compare the value of example_function and other_name_for_example_function which in this case is the same "function mechanism".
Now, lambdas are another way to define a function but it's more restricted and the function isn't assigned a name automatically. Let's take the same example but with lambdas:
>>> example_lambda = lambda argument: argument * 42
>>> other_name_for_example_lambda = example_lambda
>>> example_lambda(3)
126
>>> other_name_for_example_lambda(3)
126
>>> example_lambda == other_name_for_example_lambda
True
>>> example_lambda is other_name_for_example_lambda
True
Now if we replace the function call of your example with its content, it would look like this:
>>> n = 3 # just you see where that value will be used
>>> mytripler = lambda a: a * n
>>> a = 11 # also to see where that value will be used
>>> mytripler(a)
33
So, in your example,
myfunc() provide a "function mechanism" as a return value. In the definition of that "function mechanism", you have inserted the value 3 which is an argument of myfunc()
You assign the name mytripler to that function returned
You call it like you would with any function
Does that help you understand?

Related

How can I call a lambda without defining it as a function?

For lambda functions in the following code,
def myfunc(n):
return lambda a : a * n
mydoubler = myfunc(2)
print(mydoubler(11))
I am trying to understand why mydoubler becomes <class 'function'> and how I can call mydoubler(11) without defining it as a function.
A lambda is a function, but with only one expression (line of code).
That expression is executed when the function is called, and the result is returned.
So the equivalent of this lambda:
double = lambda x: x * 2
is this def function:
def double(x):
return x * 2
You can read more here
A lambda is a function, so your code is doing something like
def myfunc(n):
def result(a):
return a * n
return result # returns a function
mydoubler = myfunc(2)
print(f(11))
You're asking how to call mydoubler without defining it as a function, which isn't the clearest question, but you can call it without naming it like so
print( myfunc(2)(11) )
Your myfunc is returning a lambda. Lambda is a small anonymous function. A lambda can take any number of arguments, but can only have one expression.
So after execution of the 3rd line, your mydoubler will become a lambda that's why when you try print(type(mydoubler)) it will return <class 'function'>.
Also in order to call mydoubler with 11, it must be function.
A lambda expression, like a def statement, defines functions. Your code could be equivalently written as
def myfunc(n):
def _(a):
return a * n
return _
mydoubler = myfunc(2)
print(mydoubler(11))
Because the inner function is simple enough to be defined as a single expression, using a lambda expression saves you the trouble of coming up with the otherwise unused name the def statement requires.
The key here is that the inner function closes over the value of n, so that the function returned by myfunc retains a reference to the value of the argument passed to myfunc. That is, mydoubler is hard-coded to multiply its argument by 2, rather than whatever value n may get later. (Indeed, the purpose of the closure is to create a new variable n used by the inner function, one which cannot easily be changed from outside myfunc.)
using decorator you can achive this
from functools import wraps
def decorator_func_with_args(arg1):
def decorator(f):
#wraps(f)
def wrapper(val):
result = f(val)
return result(arg1)
return wrapper
return decorator
#decorator_func_with_args(arg1=2)
def myfunc(n):
return lambda arg:arg*n
result = myfunc(1211)
print(result)
output
2422
Do you mean this?
mydoubler = lambda a : a * 2
mydoubler(11)

Can anybody explain about the closure of function in Python?

Python
Can anyone help me to understand this code, I am new to Python, how does this function work?
def makeInc(x):
def inc(y):
return y + x
return inc
incOne = makeInc(1)
incFive = makeInc(5)
print(incOne(5)) # returns 6
print(incFive(5)) # returns 10
Higher-order functions
Functions like makeInc that in turn, return another function are called higher order functions. Usually, functions are known to accept data as input and return data as output. With higher order functions, functions instead of data, either return code as output or accept code as input. This code is wrapped into a function. In Python, functions are first class citizens which means functions, just like data, can be passed around. For instance:
myvariable = print
Notice, how I have assigned print to myvariable and how I have dropped the parentheses after print Functions without parentheses are called function objects. This means myvariable now is just another name for print:
print("Hello World!")
myvariable("Hello World!")
Both of the above statements do the exact same thing. What can be assigned to variables can also be returned from functions:
def myfunction():
return print
myfunction()("Hello World!");
Now let's look at your example:
def makeInc(x):
def inc(y):
return y + x
return inc
makeInc is a function that accepts a parameter called x. It then defines another nested inner function called inc which takes in a parameter called y. The thing about nested functions is that they have access to the variables of the enclosing function as well. Here, inc is the inner function but it has access to x which is a variable of the enclosing outer scope.
The last statement return inc returns the inner function to the caller of makeInc. What makeInc essentially is doing, is creating a custom function based on the parameter it receives.
For instance:
x = makeInc(10)
makeInc will first accept 10 and then return a function that takes in an argument y and it increments y by 10.
Here, x is a function that takes in any argument y and then increments it by 10:
x(42) # Returns 52
nonlocal
However, there is a caveat when using nested functions:
def outer():
x = 10
def inner():
x = 20
inner()
print(x) # prints 10
Here, you would assume that the last print statement will print 20. But no! When you assign x = 20 in the inner function, it creates a new local variable called x which is initialized to 20. The outer x remains untouched. To modify the outer x, use the nonlocal keyword:
def outer():
x = 10
def inner():
nonlocal x = 20
inner()
print(x) # prints 20
If you are directly reading x inside inner() instead of assigning to it, you do not need nonlocal.
What is happening here is that makeInc() returns a function handle pointing to specific implementation of inc(). So, calling makeInc(5) "replaces" the x in inc(y) to 5 and returns the callable handle of that function. This handle is saved in incFive. You can now call the function as defined (inc(y)). Since you set x=5 before, the result will be y+5.

Returning Nested Functions in Python

def raise_val(n):
"""Return the inner function."""
def inner(x):
"""Raise x to the power of n."""
raised = x ** n
return raised
return inner
square = raise_val(2)
cube = raise_val(3)
print(square(2), cube(4))
Outputs:
4 64
Can anybody explain to me how come square(2) knows that the argument passed is x?
this code uses the concept of lexical closures or closures.Closures are the function that remembers the parameters passed to their parent function.The more technical definition will be,Closures are the function that remembers values in enclosing scope even if they are not actually present in the memory.
#for example`
def outer(x):
def inner():
print(f"The argument passed to outer was {x}")
'''Notice how inner() will grab the argument passed to the outer function'''
return inner
value=outer(69)
print(value())
Maybe this will help: https://stackabuse.com/python-nested-functions/
Notice you "sends arguments twice" (not really): first in square = raise_val(2) and second in square(2). What happens? The first calls return a function: you call to raise_val and it returns inner, which is a function. Now square variable actually holds a function. Second call, square(2), just call to the function.
It's the same as:
def a(x):
print(x)
square = a
print(square(5))
In this example, square holds a function. It's the same as in your code, since raise_val returns a function. Square holds inner method, and later it is been called. You send x directly: square(2) sends 2 for x of course.
A more interesting can be "how inner remembers n?", and as others mentioned in comments: it's manages variables of current scope.

Is it possible to define a functionn as a variable?

working on some code has a func. that goes through if statements I want to assign this to a vaiable that i can use to redefine a list.
everything! cries in python
Code here
Expected : Works
Actual: don't Works
Because of the fact that functions are a type of object (a callable object) a variable can be assigned an instance of that object.
def bar():
return 'foo'
x = bar
print(x) #O <function at #number>
print(x()) #Output: 'foo'
Yeah you can define a function and assign that function to a variable. Then you can call that variable by providing args like any other function.
For example.
>>> def example_function(x, y):
... return x + y
...
>>> func_var = example_function
>>> func_var(10, 20)
30
Will work. It doesn't really accomplish anything though.
If you provide an example of what you want to accomplish I can give a better example.

Nested function(Python 3)

a function (funcA) that takes a function (funcB) and returns a function that can be evaluated to produce the same value that funcB would produce (if given the same arguments) plus 1
returned_func(x) = funcB(x) + 1
What could be the possible way of doing this? I am confused with the second part of the question as to how can a function return a value and function at the same time. Any code example would be much appreciated! Thanks!
The concept you're looking for is, essentially, a function decorator. In Python, functions are first-class objects, just like class instances are in other languages. That means that you can pass them around, just like any other object. For example:
def foo(x):
return x + 1
print(foo) # <function foo at 0x0000024202F43EA0>
bar = foo
print(bar) # <function foo at 0x0000024202F43EA0>
Here we created a reference to the function object itself. We can, using the same idea, make a function which returns a function:
def foo(x):
def inner(y):
return x + y
return inner
func = foo(5)
print(func(3)) # 8
func is assigned to the return value of foo, which is itself a function that we can evaluate. You want to return a function A that adds 1 to the result of another function, B. So, pass B to a function make_A:
def make_A(b):
def inner(x):
return b(x) + 1
return inner
def B(x):
return x
A = make_A(B)
print(A(1)) # 2
Python has excellent syntactic sugar for this type of function. See this primer for more information.
def func1(x):
#operations go here:
return(x + 1)
def func2():
#operations go here:
return(x - 1)
if func1(2) == func2(4):
print("Hooray")
Does this help? It is a demonstration of how parameters and return values can interact.
A segment like func(1) implies the return value with the parameter as 1.

Categories