Функциональное программирование на python для самых маленьких
Содержание:
- Syntax and Examples
- Lambda with Built-in Functions
- Logging using Python
- Lambda, filter, reduce und map
- Handler Details for Python
- Преимущества и недостатки lambda
- Using if, elif & else in a lambda function
- Lambdas vs. Regular functions
- lambdas in filter()
- Неправильное использование: наименование лямбда-выражений
Syntax and Examples
The formal syntax to write a lambda function is as given below:
lambda p1, p2: expression
Here, p1 and p2 are the parameters which are passed to the lambda function. You can add as many or few parameters as you need.
However, notice that we do not use brackets around the parameters as we do with regular functions. The last part (expression) is any valid python expression that operates on the parameters you provide to the function.
Example 1
Now that you know about lambdas let’s try it with an example. So, open your IDLE and type in the following:
adder = lambda x, y: x + y print (adder (1, 2))
Here is the output:
3
Code Explanation
Here, we define a variable that will hold the result returned by the lambda function.
1. The lambda keyword used to define an anonymous function.
2. x and y are the parameters that we pass to the lambda function.
3. This is the body of the function, which adds the 2 parameters we passed. Notice that it is a single expression. You cannot write multiple statements in the body of a lambda function.
4. We call the function and print the returned value.
Example 2
That was a basic example to understand the fundamentals and syntax of lambda. Let’s now try to print out a lambda and see the result. Again, open your IDLE and type in the following:
#What a lambda returns string='some kind of a useless lambda' print(lambda string : print(string))
Now save your file and hit F5 to run the program. This is the output you should get.
Output:
<function <lambda> at 0x00000185C3BF81E0>
What’s happening here? Let’s look at the code to understand further.
Code Explanation
- Here, we define a string that you’ll pass as a parameter to the lambda.
- We declare a lambda that calls a print statement and prints the result.
But why doesn’t the program print the string we pass? This is because the lambda itself returns a function object. In this example, the lambda is not being called by the print function but simply returning the function object and the memory location where it is stored. That’s what gets printed at the console.
Example 3
However, if you write a program like this:
#What a lambda returns #2 x="some kind of a useless lambda" (lambda x : print(x))(x)
And run it by hitting F5, you’ll see an output like this.
Output:
some kind of a useless lambda
Now, the lambda is being called, and the string we pass gets printed at the console. But what is that weird syntax, and why is the lambda definition covered in brackets? Let’s understand that now.
Code Explanation
- Here is the same string we defined in the previous example.
- In this part, we are defining a lambda and calling it immediately by passing the string as an argument. This is something called an IIFE, and you’ll learn more about it in the upcoming sections of this tutorial.
Example 4
Let’s look at a final example to understand how lambdas and regular functions are executed. So, open your IDLE and in a new file, type in the following:
#A REGULAR FUNCTION def guru( funct, *args ): funct( *args ) def printer_one( arg ): return print (arg) def printer_two( arg ): print(arg) #CALL A REGULAR FUNCTION guru( printer_one, 'printer 1 REGULAR CALL' ) guru( printer_two, 'printer 2 REGULAR CALL \n' ) #CALL A REGULAR FUNCTION THRU A LAMBDA guru(lambda: printer_one('printer 1 LAMBDA CALL')) guru(lambda: printer_two('printer 2 LAMBDA CALL'))
Now, save the file and hit F5 to run the program. If you didn’t make any mistakes, the output should be something like this.
Output:
printer 1 REGULAR CALL
printer 2 REGULAR CALL
printer 1 LAMBDA CALL
printer 2 LAMBDA CALL
Code Explanation
- A function called guru that takes another function as the first parameter and any other arguments following it.
- printer_one is a simple function which prints the parameter passed to it and returns it.
- printer_two is similar to printer_one but without the return statement.
- In this part, we are calling the guru function and passing the printer functions and a string as parameters.
- This is the syntax to achieve the fourth step (i.e., calling the guru function) but using lambdas.
In the next section, you will learn how to use lambda functions with map(), reduce(), and filter() in Python.
Lambda with Built-in Functions
In Python, we can use the available Built-in functions along with lambda function.
Python lambda filter Example
In this example, we are going to use the built-in filter function to filter the sequence of list items. First, we declared a list of numbers from 1 to 15. Next, we used the filter function with a lambda expression.
This Python lambda expression checks whether a number is divisible by two or not. Next, the filter function returns all the True values.
TIP: Refer to the Python List article to understand the concept of the list.
OUTPUT
Here, we extended the previous Python lambda example. This code filters and returns the Even Number, Odd Numbers, and Numbers that are divisible by 3.
OUTPUT
Lambda map Example
Unlike filter function, map function takes each list item and returns both the True and False values. In this Python lambda example, we used map function to return the boolean value. It checks each individual value is divisible by 2 equals to 0. If true, it returns True. Otherwise, it returns false.
OUTPUT
This time, we are performing multiplication using this Python lambda map function. It takes one individual list item at a time and performs the multiplication. At last, it returns the modified list.
OUTPUT
By using the map function, you can also perform calculations on multiple lists. For instance, this Python lambda example performs addition, subtraction, and multiplication of two lists. It takes one value from both the list in the same position and performs the calculation.
OUTPUT
ANALYSIS
First, x = 10 from number1, y = 15 from number2 list. By adding both of them get 25. Do the same for the remaining list items.
Lambda Reduce Example
The Python lambda reduce function accepts two values and a list as arguments values. In this example, we are going to use this function along with the lambda function.
OUTPUT
ANALYSIS
First, x = 10, y = 20. Or you can simply write it as ((((((10 + 20) + 30) + 15) + 25) + 35) + 45)
Lambda Built-in function Example
Until now, we are using the Python lambda expression to calculate something or performing numerical operations. However, you can use them on string data as well.
In this Python lambda function example, we declared a string list. Next, we used the sorted function to sort the list items. However, we used the sorted key as a lambda expression. Within this expression, we are using the len function to find the length of each word. It means sorting is done based on the item length.
OUTPUT
Logging using Python
To log info using Python, we can use print or logger function available. Let us use the above example of context and check inCloudWatch to see if the logs are printed. Observe the following code −
def my_handler(event, context): print("Log stream name:", context.log_stream_name) print("Log group name:", context.log_group_name) print("Request ID:",context.aws_request_id) print("Mem. limits(MB):", context.memory_limit_in_mb) print("Time remaining (MS):", context.get_remaining_time_in_millis()) return "aws lambda in python using zip file"
The output of this code in CloudWatch is as shown below −
Observe the following example to understand about using logger to print logs to CloudWatch −
import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def my_handler(event, context): logger.info('Using logger to print messages to cloudwatch logs') return "aws lambda in python using zip file"
The output for this will be as shown in the screenshot given below −
Lambda, filter, reduce und map
Lambda-Operator
Die einen lieben ihn, die anderen hassen ihn und viele fürchten ihn,
den Lambda-Operator. Als Multiparadigmensprache unterstützt Python auch
die funktionale Programmierung. Lambda-Funktionen kommen aus der funktionalen
Programmierung. Mit Hilfe des lambda-Operators können anonyme Funktionen, d.h.
Funktionen ohne Namen erzeugt werden. Sie haben eine beliebe Anzahl von
Parametern, führen einen Ausdruck aus und liefern den Wert dieses Ausdrucks
als Rückgabewert zurück.
Anonyme Funktionen sind insbesondere bei der Anwendung der map-, filter-
und reduce-Funktionen von großem Vorteil.
Allgemeiner Aufbau einer Lambda-Funktion:
lambda Argumentenliste: Ausdruck
Die Argumentenliste besteht aus einer durch Kommata getrennten Liste von Argumenten und der Ausdruck ist ein Ausdruck der diese Argumente benutzt.
Beispiel:
>>> f = lambda x, y : x + y >>> f(1,1) 2
map-Funktion
r = map(func, seq)
funcseqmapfuncseq
def fahrenheit(T): return ((9.0/5)*T + 32) def celsius(T): return (5.0/9)*(T-32) temp = (36.5, 37, 37.5,39) F = map(fahrenheit, temp) C = map(celsius, F)
>>> Celsius = >>> Fahrenheit = map(lambda x: (float(9)/5)*x + 32, Celsius) >>> print Fahrenheit >>> C = map(lambda x: (float(5)/9)*(x-32), Fahrenheit) >>> print C >>>
>>> a = >>> b = >>> c = >>> map(lambda x,y:x+y, a,b) >>> map(lambda x,y,z:x+y+z, a,b,c) >>> map(lambda x,y,z:x+y-z, a,b,c)
Filtern
>>> fib = >>> result = filter(lambda x: x % 2, fib) >>> print result >>> result = filter(lambda x: x % 2 == 0, fib) >>> print result >>>
reduce-Funktion
123n
- zuerst wird func auf die beiden ersten Argumente s1 und
s2 angewendet. Das Ergebnis ersetzt die beiden Elemente s1 und
s2
Die Liste sieht damit wie folgt aus:
[ func(s1, s2), s3, … , sn ] - Im nächsten Schritt wird func auf func(s1, s2)
und s3 angewendet.
Die Liste sieht damit wie folgt aus:
[ func(func(s1, s2),s3), … , sn ] - Dies wird solange fortgesetzt bis nur noch ein Element übrig bleibt, d.h.
man hat die Liste auf ein Element reduziert.
>>> reduce(lambda x,y: x+y, ) 113
Kritik von Guido van Rossum
Voriges Kapitel: Reguläre Ausdrücke, FortgeschritteneNächstes Kapitel: Listen-Abstraktion (List Comprehension)
Handler Details for Python
Note that the handler has to be name of the file followed by name of the function. In the above case, our file name is hellopython.py and name of the function is my_handler; so the handler will be hellopython.my_handler.
Once the upload is done and changes are saved, it actually shows the details of the zip file in the online editor in AWS Lambda console. Now, let us test the code to see the output and logs.
Now, let us understand the details of the Lambda function using the following sample code −
def my_handler(event, context): return "aws lambda in python using zip file"
In the above code, the function name my_handler is having 2 params, event and context.
Преимущества и недостатки lambda
Мое представление о лямбда-выражениях можно описать как постоянное сравнение с использованием def для определения функций. Оба этих инструмента дают нам функции, но каждый из них имеет разные ограничения и используют разный синтаксис.
Лямбда-выражения отличаются от def по следующим признакам:
- Их можно передавать мгновенно (переменная не нужна);
- Они могут содержать только одну строку кода;
- Они возвращаются автоматически;
- Они не могут содержать docstring и иметь наименование;
- Синтаксис отличается и мало знаком.
Тот факт, что lambda-выражения могут свободно передаваться является главным преимуществом. Автоматический возврат — тоже удобно, но его с трудом можно назвать весомым преимуществом, на мой взгляд.
Наличие единственной строки кода я не вижу ни как преимуществом, ни как недостатком. Тот факт, что лямбда функции не имеют docstring и не имеют наименований — может быть неудобно, а незнакомый синтаксис — стать проблемой для новичков в Python.
Using if, elif & else in a lambda function
Till now we have seen how to use if else in a lambda function but there might be cases when we need to check multiple conditions in a lambda function. Like we need to use if , else if & else in a lambda function. We can not directly use elseif in a lambda function. But we can achieve the same effect using if else & brackets i.e.
lambda <args> : <return Value> if <condition > ( <return value > if <condition> else <return value>)
Create a lambda function that accepts a number and returns a new number based on this logic,
- If the given value is less than 10 then return by multiplying it by 2
- else if it’s between 10 to 20 then return multiplying it by 3
- else returns the same un-modified value
# Lambda function with if, elif & else i.e. # If the given value is less than 10 then Multiplies it by 2 # else if it's between 10 to 20 the multiplies it by 3 # else returns the unmodified same value converter = lambda x : x*2 if x < 10 else (x*3 if x < 20 else x)
print('convert 5 to : ', converter(5)) print('convert 13 to : ', converter(13)) print('convert 23 to : ', converter(23))
convert 5 to : 10 convert 13 to : 39 convert 23 to : 23
Complete example is as follows,
def main(): print('*** Using if else in Lambda function ***') # Lambda function to check if a given vaue is from 10 to 20. test = lambda x : True if (x > 10 and x < 20) else False # Check if given numbers are in range using lambda function print(test(12)) print(test(3)) print(test(24)) print('*** Creating conditional lambda function without if else ***') # Lambda function to check if a given vaue is from 10 to 20. check = lambda x : x > 10 and x < 20 # Check if given numbers are in range using lambda function print(check(12)) print(check(3)) print(check(24)) print('*** Using filter() function with a conditional lambda function (with if else) ***') # List of numbers listofNum = print('Original List : ', listofNum) # Filter list of numbers by keeping numbers from 10 to 20 in the list only listofNum = list(filter(lambda x : x > 10 and x < 20, listofNum)) print('Filtered List : ', listofNum) print('*** Using if, elif & else in Lambda function ***') # Lambda function with if, elif & else i.e. # If the given value is less than 10 then Multiplies it by 2 # else if it's between 10 to 20 the multiplies it by 3 # else returns the unmodified same value converter = lambda x : x*2 if x < 10 else (x*3 if x < 20 else x) print('convert 5 to : ', converter(5)) print('convert 13 to : ', converter(13)) print('convert 23 to : ', converter(23)) if __name__ == '__main__': main()
Output:
*** Using if else in Lambda function *** True False False *** Creating conditional lambda function without if else *** True False False *** Using filter() function with a conditional lambda function (with if else) *** Original List : Filtered List : *** Using if, elif & else in Lambda function *** convert 5 to : 10 convert 13 to : 39 convert 23 to : 23
Lambdas vs. Regular functions
As previously stated, lambdas are just functions which do not have an identifier bound to them. In simpler words, they are functions with no names (hence, anonymous). Here is a table to illustrate the difference between lambdas and regular functions in python.
Lambdas
Regular Functions
Syntax:
lambda x : x + x
Syntax:
def (x) : return x + x
Lambda functions can only have one expression in their body.
Regular functions can have multiple expressions and statements in their body.
Lambdas do not have a name associated with them. That’s why they are also known as anonymous functions.
Regular functions must have a name and signature.
Lambdas do not contain a return statement because the body is automatically returned.
Functions which need to return value should include a return statement.
Explanation of the differences?
The primary difference between a lambda and a regular function is that the lambda function evaluates only a single expression and yields a function object. Consequently, we can name the result of the lambda function and use it in our program as we did in the previous example.
A regular function for the above example would look like this:
def adder (x, y): return x + y print (adder (1, 2))
Here, we have to define a name for the function which returns the result when we call it. A lambda function doesn’t contain a return statement because it will have only a single expression which is always returned by default. You don’t even have to assign a lambda either as it can be immediately invoked (see the next section). As you will see in the following example, lambdas become particularly powerful when we use them with Python’s built-in functions.
However, you may still be wondering how lambdas are any different from a function that returns a single expression (like the one above). At the interpreter level, there is not much difference. It may sound surprising, but any lambda function that you define in Python is treated as a normal function by the interpreter.
As you can see in the diagram, the two definitions are handled in the same way by the python interpreter when converted to bytecode. Now, you cannot name a function lambda because it is reserved by Python, but any other function name will yield the same bytecode.
Summary
- Lambdas, also known as anonymous functions, are small, restricted functions which do not need a name (i.e., an identifier).
- Every lambda function in Python has 3 essential parts:
- The lambda keyword.
- The parameters (or bound variables), and
- The function body.
- The syntax for writing a lambda is: lambda parameter: expression
- Lambdas can have any number of parameters, but they are not enclosed in braces
- A lambda can have only 1 expression in its function body, which is returned by default.
- At the bytecode level, there is not much difference between how lambdas and regular functions are handled by the interpreter.
- Lambdas support IIFE thru this syntax: (lambda parameter: expression)(argument)
- Lambdas are commonly used with the following python built-ins:
- Filter: filter (lambda parameter: expression, iterable-sequence)
- Map: map (lambda parameter: expression, iterable-sequences)
- Reduce: reduce (lambda parameter1, parameter2: expression, iterable-sequence)
- Do not write complicated lambda functions in a production environment because it will be difficult for code-maintainers.
I’ve added a table, but the explanation is necessary to understand the differences.
lambdas in filter()
The filter function is used to select some particular elements from a sequence of elements. The sequence can be any iterator like lists, sets, tuples, etc.
The elements which will be selected is based on some pre-defined constraint. It takes 2 parameters:
- A function that defines the filtering constraint
- A sequence (any iterator like lists, tuples, etc.)
For example,
sequences = filtered_result = filter (lambda x: x > 4, sequences) print(list(filtered_result))
Here’s the output:
Code Explanation:
1. In the first statement, we define a list called sequences which contains some numbers.
2. Here, we declare a variable called filtered_result, which will store the filtered values returned by the filter() function.
3. A lambda function which runs on each element of the list and returns true if it is greater than 4.
4. Print the result returned by the filter function.
Неправильное использование: наименование лямбда-выражений
PEP8, являющийся официальным руководством Python, рекомендует писать код таким образом:
Python
normalize_case = lambda s: s.casefold()
1 | normalize_case=lambdass.casefold() |
Указанный вверху оператор создает анонимную функцию и затем присваивает её переменной. Этот код игнорирует причину, по которой лямбда функции являются полезными:
Если вы хотите создать однострочную функцию и хранить ее в переменной, вам нужно использовать def вместо этого:
Python
def normalize_case(s): return s.casefold()
1 | defnormalize_case(s)returns.casefold() |
Это рекомендуется в PEP8, так как названные функции — это простой и понятный элемент. Также полезно давать функции правильное наименование, чтобы упростить лечение возможных багов. В отличие от функций, определенных при помощи def, функции лямбда никогда не имеют названий (название всегда будет <lambda>):
Python
>>> normalize_case = lambda s: s.casefold()
>>> normalize_case
<function <lambda> at 0x7f264d5b91e0>
>>> def normalize_case(s): return s.casefold()
…
>>> normalize_case
<function normalize_case at 0x7f247f68fea0>
1 |
>>>normalize_case=lambdass.casefold() >>>normalize_case <function<lambda>at0x7f264d5b91e0> >>>defnormalize_case(s)returns.casefold() … >>>normalize_case <function normalize_case at0x7f247f68fea0> |
Если вы хотите создать функции и хранить ее в переменной, определите вашу функцию при помощи def. Это именно то, для чего он нужен
Неважно, если ваша функция длиной в одну строку кода, или вы определяете функцию внутри другой функции, def отлично работает в таких случаях