# Python functional programming guide (2)

Source: Internet
Author: User
As a parameter

If you are familiar with the OOP template method mode, you can quickly learn to pass functions as parameters. The two are basically the same, but here we pass the function itself rather than the object that implements an interface.
Let's warm-up the previously defined summation function Add:

?
 1 `Print` `Add (``'Tree of triangles'``,``'Arctic'``)`

Unlike the addition operator, you must be surprised that the answer is 'trigonometric function '. This is a built-in egg... bazinga!

Let's get down to the truth. Our customers have a list from 0 to 4:

?
 1 `LST``=` `Range``(``5``)``# [0, 1, 2, 3, 4]`

Although we have given him an operator in the previous section, he is still worried about how to calculate the sum of all elements in this list. Of course, this task is very easy for us:

?
 123 `Amount``=` `0``For` `Num``In` `LST:``Amount``=` `Add (amount, num)`

This is a typical script style.CodeNo problem at all. You can certainly get the correct result. Now, let's try to refactor it with a functional style.

First of all, we can foresee that the summation action is very common. If we abstract this action into a separate function, when we need to sum up another list, you don't have to write this routine again:

?
 1234567 ` def ` ` sum _ (LST ): ` ` ` ` amount ` ` = ` ` 0 ` ` ` ` for ` ` num ` ` in ` ` lst: ` ` ` ` amount ` ` = ` ` Add (amount, num) ` ` ` ` return ` ` amount ` ` Print ` ` sum _ (LST) `

Continue. The sum _ function defines a process as follows:
1. Add the initial value to the first element of the list;
2. Add the result of the last addition to the next element of the list;
3. Repeat Step 2 until there are no more elements in the list;
4. Return the result of the last addition.

If the product is required now, we can write a similar process-simply replace the sum with the multiplication:

?
 12345 ` def ` ` multiply (LST ): ` ` ` ` product ` ` = ` ` 1 ` ` ` ` for ` ` num ` ` in ` ` lst: ` ` ` ` product ` ` = ` ` product ` ` * ` ` num ` ` ` ` return ` ` product `

Except for changing the initial value to 1 and the function add to the multiplication operator, all other code is redundant. Why don't we abstract this process and pass in addition, multiplication, or other functions as parameters?

?
 1234567 ` def ` ` reduce _ (function, lst, initial): ` ` ` ` result ` ` = ` ` initial ` ` ` ` for ` ` num ` ` in ` ` lst: ` ` ` ` result ` ` = ` ` function (result, num) ` ` ` ` return ` ` result ` ` Print ` ` reduce _ (add, LST, ` ` 0 ` `) `

To calculate the product, do the following:

?
 1 `Print` `Reduce _(``Lambda` `X, Y: x``*` `Y, lst,``1``)`

So what should we do if we want to use reduce _ to find the maximum value in the list? Please think about it yourself :)

Although there is a design pattern such as the template method, such complexity often makes people prefer to write loops everywhere. Using functions as parameters completely avoids the complexity of the template method.

Python has a built-in reduce function that fully implements and extends the reduce _ function. Later in this article, we will introduce some useful built-in functions. Note that our purpose is to avoid loops. Replacing loops with functions is the most obvious feature of the functional style that distinguishes it from the directive style.

* A function-based language built on C language like python provides the ability to write loop code. Although built-in functions provide function-based programming interfaces, but it is usually implemented in a loop. Similarly, if you find that built-in functions cannot meet your cycle needs, you may also encapsulate them and provide an interface.

Return Value

Returning a function usually needs to be used with a closure (that is, returning a closure) to exert its power. Let's first look at the definition of a function:

?
 12345 `Def` `Map _ (function, LST ):``Result``=` `[]``For` `Item``In` `LST:``Result. append (function (item ))``Return` `Result`

Function Map _ encapsulates the most common iteration: calls a function for each element in the list. Map _ requires a function parameter and saves the result of each call to a list to return. This is a directive practice. When you know the list resolution (list comprehension), it will be better implemented.

Here we will skip the poor implementation of map _ and focus only on its functions. For the lst in the previous section, you may find that the final result of the product is always 0, because the lst contains 0. To make the results look large enough, we use map _ to add 1 to each element in the lst:

?
 12 `LST``=` `Map _(``Lambda` `X: add (``1``, X), LST)``Print` `Reduce _(``Lambda` `X, Y: x``*` `Y, lst,``1``)`

The answer is 120, which is far from big enough. Again:

?
 12 `LST``=` `Map _(``Lambda` `X: add (``10``, X), LST)``Print` `Reduce _(``Lambda` `X, Y: x``*` `Y, lst,``1``)`

Actually, I didn't really think the answer would be 360360. I swear I didn't accept any benefit from Zhou Hongyi.

Now let's look at the two lambda expressions we have written: the similarity is over 90%, which can be described as plagiarism. But the question is not plagiarism, but whether many characters are written? If there is a function that generates an addition function based on the specified left operand, it is used as follows:

?
 1 `LST``=` `Map _ (add_to (``10``), LST)``# Add_to (10) returns a function that accepts a parameter and adds 10.`

It should be quite comfortable to write. The following is the implementation of the add_to function:

?
 12 `Def` `Add_to (n ):``Return` `Lambda` `X: add (n, x)`

By specifying several parameters for an existing function to generate a new function, this function can implement all functions of the original function by passing in the remaining unspecified parameters, this is called a partial function. Python's built-in functools module provides a function partial that can generate partial functions for any function:

?
 1 `Functools. Partial (func [,``*``ARGs] [,``*``*``Keywords])`

You need to specify the function to generate the partial function, and specify several parameters or named parameters. Then, partial returns this partial function. However, partial returns not a function strictly, it is an object that can be called directly like a function. Of course, this will not affect its function.

Another special example is the decorator. The decorator is used to enhance or even change the functions of the original function. I have written a document about the decorator at http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html.

* In other functional languages (such as Scala), you can use the currying technology to achieve elegance. Curialization converts a function that accepts multiple parameters into a function that accepts a single parameter (the first parameter of the initial function, and return the technology of the new function that accepts the remaining parameters and returns results. The following pseudo code is shown:

?
 12345 `# Not real code``Def` `Add (x) (y ):``# Kerihua``Return` `X``+` `Y` `LST``=` `Map _ (add (``10``), LST)`

The add function is colized so that add accepts the first parameter X and returns a function that accepts the second parameter Y, calling this function is exactly the same as add_to (returns x + y) in the previous article, and you do not need to define add_to. Does it seem more refreshing? Unfortunately, Python does not support colitization.

Some built-in functions
• Reduce (function, iterable [, initializer])
The main function of this function is the same as the reduce _ defined by us. Two additional points are required:
Its second parameter can be any iteratable object (the object implementing the _ ITER _ () method );
If the third parameter is not specified, the first two elements of iterable are used as the parameters when the function is called for the first time.
The built-in functions listed below are combined by reduce and some common functions:

?  12345 ` All `` (Iterable) `` = `` = ` ` Reduce `` ( `` Lambda ` ` X, Y: `` Bool `` (X `` And ` ` Y), iterable) `` Any ``(Iterable) `` = `` = ` ` Reduce `` ( `` Lambda ` ` X, Y: `` Bool `` (X `` Or ` ` Y), iterable) `` Max `` (Iterable [, argS...] [, key]) `` = `` = ` ` Reduce `` ( `` Lambda ` ` X, Y: x ``If ` ` Key (x)> key (y) `` Else ` ` Y, iterable_and_args) `` Min `` (Iterable [, argS...] [, key]) `` = `` = ` ` Reduce `` ( `` Lambda ` ` X, Y: x `` If ` ` Key (x)
• Map (function, iterable ,...)
The main function of this function is the same as the map _ defined by us. You need to add:
Map can also accept multiple iterable parameters. When calling function n, iterable1 [N], iterable2 [N],... is used as the parameter.
• Filter (function, iterable)
This function filters out all elements in iterable that return true or bool (Return Value) as true when the function is called with the element itself as a parameter and returns the result in a list, it is the same as the my_filter function in the first part of the series.
• Zip (iterable1, iterable2 ,...)
This function returns a list. Each element is a tuples that contain (iterable1 [N], iterable2 [N],...).
Example: Zip ([1, 2], [3, 4]) --> [(1, 3), (2, 4)]
If the length of the parameter is inconsistent, it ends at the end of the shortest sequence. If no parameter is provided, an empty list is returned.

You can also use functools. Partial () mentioned in section 2.5 to create common partial functions for these built-in functions.

In addition to these built-in functions, there is a module named functional in pypi that provides more interesting functions. However, because there are not many use cases and additional installation is required, we will not introduce them in this article. However, I recommend that you download the python-only implementation of this module.Source codeLook, broaden your mind. The functions inside are very short, the source file is a total of less than 300 lines, the address here: http://pypi.python.org/pypi/functional

Related Keywords:
Related Article

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

## A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

• #### Sales Support

1 on 1 presale consultation

• #### After-Sales Support

24/7 Technical Support 6 Free Tickets per Quarter Faster Response

• Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.