When I was doing lab, I saw a lambda function
, so I included the meaning of a review.
Lambda Function
In a nutshell, you can easily assign a function to an appropriate variable using lambda.
bind a function to a name using the same syntax and assignment statement.
First, consider the following expression.
>>> x = 10
>>> square = x*x
>>> square
100
>>> square = lamnda x: x*x
>>> square
<function...>
>>> square(4)
16
>> square(10)
100
I tried to summarize it in a simple figure with reference to the lecture slides.
def
and lambda
To summarize the differences with reference to the above example:
There is not much difference in basic operation. So what's the difference after all? Write Environmental diagram You can see it by trying. The following is a screenshot of the lecture slides.
If you create a function with def
, the name will be given on the spot, but if you create a function with lambda
, even if the function is completed, you will not have a name until you finish assigning the name by ʻassignment statement. That is. In other words, in python, you can create a function on the spot when you need it, without having to use
def statement` to name it.
A lambda expression evaluates to a function that has a single return expression as its body.
As a result of executing lambda expression
, it becomes lambda function
and plays a role as a function. This function doesn't have an innate name, so python simply writes it as <lambda>
.
>>> s = lambda x: x * x
>>> s
<function<lambda> at xxxxxxx>
>>> s(12)
144
Other than that, there is no basic difference.
Translating between named and anonymous functions
I wondered (and I might have written it somewhere), but when I compare the two expressions lambda x, y
and lambda x: lambda y
, there is a difference other than the number of parameters and the argument. There wasn't.
>>> adder = lambda x: lambda y: x + y
>>> adder2 = lambda x, y: x + y
>>> adder(1)(3)
4
>>> adder2(1,3)
4
However, the difference became clearer by comparing def
and lambda
when I participated in the review sesh.
If you think about it, this is easy to understand if you think of the second lambda
as def helper (y): return
in def
.
Higher-Order Functions can be done easily.
def compose1(f,g):
return lambdax : f(g(x))
f = compose1(lamnda x: x * x,
lambda y: y + 1)
result = f(12) # 169
<a href="http://www.pythontutor.com/visualize.html#code=def+compose1(f,g%29%3A%0A++++return+lambda+x%3A+f(g(g(g) x% 29% 29% 0A% 0Af +% 3D + compose1 (lambda + x% 3A + x + * + x,% 0A ++++++++++++++ lambda + y% 3A + y +% 2B + 1% 29% 0A% 0Aresult +% 3D + f (12% 29 & mode = display & origin = opt-frontend.js & cumulative = false & heapPrimitives = false & textReferences = false & py = 3 & rawInputLstJSON =% 5B% 5D & curInstr = 0 "target =" _ blank "> PythonTutor.com </ strong> You can see the more accurate function behavior with a>.
Note that the lambda x: f (g (x))
function inside the compose1
function is made with f1 frame instead of global frame. The reason is that only when compose1
is called byf
does it enter into compose1
. By the time you call compose1
, you have already created an f1 frame, so [p = g]. Another thing I noticed is about the two lambdas I'm passing as arguments to the compose1
function. Personally, I thought that it would be defined when I called the compose1
function, so I wrote [p = f1], but apparently when I defined it ascompose1 (f, g)
above ( I've assigned a name to the variable (regardless of what I receive), so I think the result is [p = g] no matter what I throw in as lambda
later. If you make a mistake in using such a lambda, it will become more difficult to understand.
lambda expressions are notoriously illegible, despite their brevity.
What this means is that you can write the above function as compose1 = lambda f, g: lambda x: f (g (x))
, but it often takes some time to fully understand.
lambda
Apparently, lambda
was born because the writer at that time couldn't write the mathematical expression $ ŷ. Y * y $ with a typewriter. They rewrote the expression as $ Λ y. Y x y $, so it became $ λ y. Y x y $, and they still see the symbol $ λ $. For more information, see Peter Norvig.
I will write what I noticed while doing the problem of lab02.
Question 1: WWPP: Lambda the Free
Q1
>>> c = lambda: 3
>>> c()
3
As an option
None
as value (w / some part missing?)3
but None
is value (= print)3
as value (= return)
Is it about? However, as you can see from the above explanation, it is thought that return
is congenitally attached to lambda, so it is naturally the same as def c (): return 3
. That is, it returns 3
.Q2
>>> c = lambda x: lambda: print('123')
>>> c(88)
<function <lambda>.<locals>.<lambda> at 0x1013740d0>
I'm not confident that I'm 100% hit, but <a href="http://www.pythontutor.com/visualize.html#code=c+%3D+lambda+x%3A+lambda%3A+print(%22123%) 22% 29% 0Ac (88% 29% 0Ac (% 29 (88% 29% 0Ac (88% 29 (% 29 & mode = display & origin = opt-frontend.js & cumulative = false & heapPrimitives = false & textReferences = false & py = 3 & rawInputLstJSON =% 5B% 5D & curInstr = 4) From "target =" _ balnk "> pythontutor.com , you can read that c
has the structure lambda x:
that returns lambda: print ('123)
. ~~ Probably Since the second lambda is not called as a function in the first place, it seems that the first lambda is __ which took the second lambda as a function and returned the function as it is. As I noticed from, I thought that if you put lambda in lambda, the first lambda function will take the second lambda function and return it as
>>> d = lambda f: f(4) # They can have functions as arguments as well.
>>> def square(x):
... return x * x
>>> d(square)
16
In other words, just call the second one.
>>> c = lambda x: lambda: print('123')
>>> c(88)()
123
However, you need to be careful about how you call it. Because the second lambda doesn't have the ability to take arguments. Same as def foo (): print ("123 ")
. So if you try:
>>> c(88)(3333)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes 0 positional arguments but 1 was given
I throw an error. The improvement method is simply to give an argument.
>>> c = lambda x: lambda y: print("123")
>>> c(88)(333)
123
>>> c(88)()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'y'
However, if you do this, on the contrary, if there is nothing to receive as an argument, an error will be thrown, so be careful.
Q3
>>> t = lambda f: lambda x: f(f(f(x)))
>>> s = lambda x: x + 1
>>> t(s)(0)
3
For more information, <a href="http://www.pythontutor.com/visualize.html#code=t+%3D+lambda+f%3A+lambda+y%3A+f(f(f(y%29%29) % 29% 0As +% 3D + lambda + x% 3A + x% 2B1% 0At (s% 29 (0% 29% 0A & mode = display & origin = opt-frontend.js & cumulative = false & heapPrimitives = false & textReferences = false & py = 3 & rawInputLstJSON =% 5B% 5D & curInstr = Please refer to 0 "target =" _ blank "> pythontutor.com , butt (s) (0)
is(s)
and(0)
one by one s
to It may be easier to understand if you pay attention to calling in the order of 0
and what each variable of lambda
points to.
By the way, the variable in lambda does not have to be x
. The reason is that when you receive it, you receive it as a variable that you specify as you like. Nothing is limited to lambda.
>>> t = lambda f: lambda y: f(f(f(y)))
>>> s = lambda x: x+1
>>> t(s)(0)
3
Q4
>>> bar = lambda y: lambda x: pow(x, y)
>>> bar()(15)
TypeError: <lambda>() missing 1 required positional argument: 'y'
This is because there is no argument corresponding to lambda y
. It works with bar (some #) (15)
.
Q5
>>> foo = lambda: 32
>>> foobar = lambda x, y: x // y
>>> a = lambda x: foobar(foo(), bar(4)(x))
>>> a(2)
2
I think this is made for Higher-Order functions rather than lambda
, so I don't think it's necessary to explain that much.
Q6
>>> b = lambda x, y: print('summer') # When is the body of this function run?
# Nothing gets printed by the interpreter
>>> c = b(4, 'dog')
summer
>>> print(c)
None
This should be obvious if you understand pure non-pure functions.
Question 2: Question 2: Lambda the Environment Diagram
>>> a = lambda x: x * 2 + 1
>>> def b(b, x):
... return b(x + a(x))
>>> x = 3
>>> b(a, x)
The question of whether to apply the above code in an environmental diagram.
When writing an environmental diagram, remember to name the frame using the function's intrinsic name instead of the function's variable name.
Question 3: Lambdas and Currying
Write a function lambda_curry2 that will curry any two argument function using lambdas. See the doctest if you're not sure what this means.
"""Returns a Curried version of a two argument function func.
>>> from operator import add
>>> x = lambda_curry2(add)
>>> y = x(3)
>>> y(5)
8
"""
"*** YOUR CODE HERE ***"
return
A problem that can be easily solved by paying attention to which function receives which value. For example, you can see from x = lambda_curry2 (add)
that the lambda_curry2
function takes the function as an argument. Next, enter the numbers one by one in the variable y
and 8
is returned. So we come to the conclusion that lambda receives the number 2 and the rest of the process should use the function that lambda_curry2
fetched. So the answer is return lambda x: lambda y: func (x, y)
. The question was why return lambda x, z: func (x, z)
doesn't work, but it's y = x (3) (5)
when calling λ. I think it's just the difference between = (3,5) `.
>>> def lambda_curry(func):
... return lambda x, y: func(x,y)
>>> from operator import add
>>> x = lambda_curry(add)
>>> y = x(3)(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'y'
>>> l = x(3,5)
>>> l
8
The rest of the problems have been solved, but higher-order functions is involved, so I can study it a little deeper and explain it to others. I will update it when I reach the level.
Lambda w/ List Comprehension
I found that I can do some practical things with lambda
and list comprehension, so I have a memorandum.
It's not a very efficient way to search, but when searching for a prime number, you can use lambda
to write:
nums = range(2,30)
for i in range(2,8):
nums = list(filter(lambda x: x == i or x % i, nums))
print(nums)
The other is to find a suitable sentence, put it as a sentence, and then run the following script to put the number of characters for each word in the list and return it. For example:
sentence = "I was a joke, and my life was a joke."
print(list(map(lambda x: len(x), sentence.split(" ")))) # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
print(len(list(map(lambda x: len(x), sentence.split(" "))))) # 10 (=# of words)
Recommended Posts