python3x: lambda function

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.

Definition

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.

Screen Shot 2016-02-07 at 8.28.42 PM.png

Difference between 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.

Screen Shot 2016-02-07 at 8.51.23 PM.png

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.

Screen Shot 2016-02-07 at 9.05.55 PM.png

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.

Screen Shot 2016-02-17 at 7.26.35 PM.png

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.

Origin of 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.

Bullet what you noticed using lambda

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

  1. Put None as value (w / some part missing?)
  2. Display 3 but None is value (= print)
  3. Put 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 . * By the way, lambdas can also receive functions (or maybe they're used more often).

>>> 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.

Screen Shot 2016-02-08 at 1.29.03 AM.png

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)

Referenced link

-Python: Lambda Functions

Recommended Posts

python3x: lambda function
lambda
Write AWS Lambda function in Python
[Python] Make the function a lambda function
python function ①
[Python] function
In-function function
Lambda expression
Lambda function to take AMI backup (python)
Recursive function
In-function function
python function ②
Function review
[Piyopiyokai # 1] Let's play with Lambda: Creating a Lambda function
Lambda function deploy best practices with CircleCI + Lamvery