10分钟学习函数式Python( 三 )


带函数的部分应用部分应用(也称为闭包)很奇怪,但是也很酷 。我们可以调用一个函数而不提供它需要的所有参数 。我们来在一个例子中看一下这一点 。我们想要创建一个函数,它接受两个参数,一个基数和一个指数,然后返回基数的指数次方,就像这样:

10分钟学习函数式Python

文章插图
 
现在我们想要一个专用的平方函数,来使用power数求出一个数的平方:
10分钟学习函数式Python

文章插图
 
这是可行的,但如果我们想要一个立方函数呢?或者一个4次方函数呢?我们能一直写下去吗?嗯,我们可以 。但是程序员是很懒的 。如果我们重复地做同一件事时,这是一个信号,表明有一种更快的方法来加快做这些事情的速度,那将允许我们不再重复地做这些事情 。我们可以在这里使用部分应用 。让我们看一个使用了一个部分应用的平方函数的例子:
10分钟学习函数式Python

文章插图
 
这难道不酷吗?我们可以通过告诉Python第二个参数是什么来只使用一个参数调用需要两个参数的函数 。
我们还可以使用一个循环,来生成一个幂函数,其运行范围可以从立方到1000次幂 。
10分钟学习函数式Python

文章插图
 
函数式编程不是Python化您可能已经注意到了,我们在函数式编程中想要做的很多事情都是围绕列表进行的 。除了reduce函数和部分应用外,我们所看到的所有函数都会生成列表 。Guido (Python的发明者)不喜欢Python中的函数式的东西,因为Python已经有了自己的生成列表的方法 。
如果我们在一个Python IDLE会话中输入“import this”,我们会得到:
10分钟学习函数式Python

文章插图
 
这就是Python之禅 。这是一首关于某些东西Python化意味着什么的诗 。这里我们要涉及的部分是: 应该有一种——最好是只有一种——显而易见的方法来做到它 。
在Python中,map 与 filter可以做与列表表达式(接下来讨论)相同的事情 。这打破了Python之禅中的一条规则,因此函数式编程的这些部分不是“Python式的” 。
另一个话题是Lambda 。在Python中,lambda函数是一个普通函数 。Lambda是语法糖 。这两个是等价的:
10分钟学习函数式Python

文章插图
 
一个普通函数可以做lambda函数所能做的所有事情,但反过来却不行 。一个lambda函数不能完成一个普通函数所能完成的所有工作 。
这是一个关于函数式编程为什么不能很好地适应整个Python生态系统的简短讨论 。您可能已经注意到我之前提到过列表推导式,我们现在将讨论它们 。
列表推导式之前我提到过,我们可以用列表推导式完成我们可以用map或filter所做的任何事情 。这是我们要学习的关于它们的部分 。
列表推导式是在Python中生成列表的一种方式 。其语法是:
10分钟学习函数式Python

文章插图
 
让我们对一个列表中的每个数字进行平方,并以此作为一个例子:
10分钟学习函数式Python

文章插图
 
好吧,这样我们就可以看到我们如何将一个函数应用到列表中的每一项 。我们如何来应用一个filter函数呢?好吧,看看这段之前的代码:
10分钟学习函数式Python

文章插图
 
我们可以像这样来把它转换成一个列表推导式:
10分钟学习函数式Python

文章插图
 
列表推导式支持像这样的if语句 。我们不需要再应用很多个函数来得到我们想要的东西了 。如果我们试图创造使用列表的机会,那么使用列表推导式可能会更清晰、更容易一些 。
如果我们想要对列表中所有小于0的数进行平方呢?那么,使用lambda、map和filter,我们会这样写:
10分钟学习函数式Python

文章插图
 
这有点冗长而复杂 。使用一个列表推导式,它就会变成这样:
10分钟学习函数式Python

文章插图
 
列表推导式只对列表有好处 。map和filter作用于任何可迭代对象之上,那是怎么回事呢?我们可以对遇到的任何可迭代对象使用任何推导式 。


推荐阅读