python函数案例,python是函数式编程语言吗
这篇文章给大家带来了一些关于python的知识,主要介绍了函数式编程的相关问题,即在命令式范式下,给计算机提供一系列指令,然后执行这些指令来完成任务。希望对你有帮助。
推荐:python学习教程
在本文中,您将学习什么是函数范式,以及如何使用Python进行函数编程。您还将了解列表派生和其他形式的派生。
00-1010在命令式范式中,任务是通过向计算机提供一系列指令,然后执行这些指令来完成的。当这些指令被执行时,一些状态可以被改变。例如,假设你最初将a设置为5,然后改变了a的值,这时,从变量内部值的意义上来说,你改变了a的状态。
在函数范式中,你不必告诉计算机做什么,而是告诉它这是什么。比如数字的最大公约数是多少,1到n的乘积是多少等等。
因此,变量是不能改变的。一旦你设置了一个变量,它就永远保持这个状态(注意,在纯函数式语言中,它们不是变量)。因此,函数式编程没有副作用。副作用是指一个函数改变了它本身以外的东西。让我们看一些典型Python代码的例子:
这段代码的输出是5。在函数范式中,改变变量是大忌,拥有影响其作用范围之外事物的功能也是大忌。函数唯一能做的就是计算一些东西并返回结果。
现在你可能会想,“没有变量,没有副作用?这有什么好?”这是一个很好的问题,我相信大多数人都对此感到困惑。
如果用相同的参数调用该函数两次,保证得到相同的结果。如果你学过数学函数,就会知道这个好处。这称为参考透明度。由于函数没有副作用,如果你正在构建一个计算某些东西的程序,你可以加快程序的速度。如果每次调用func(2)都返回3,我们可以把它存储在一个表中,这样可以防止程序重复运行同一个函数。
通常,在函数式编程中,我们不使用循环。我们使用递归。递归是一个数学概念,通常表示“自调用”。使用递归函数,该函数反复调用自己作为子函数。这是Python中递归函数的一个很好的例子:
有些编程语言也很懒。这意味着他们不到最后一秒不会计算或做任何事情。如果你写一些代码来执行2 ^ 2,那么函数程序只有在你真正需要使用结果的时候才会被计算。我们将很快探讨Python中的惯性。
函数范式
要理解,我们先来看看什么是迭代。通常可以迭代的对象是列表或者数组,但是Python有很多不同的可以迭代的类型。您甚至可以创建自己的对象,通过实现神奇的方法可以迭代这些对象。魔法方法就像一个API,可以帮助你的对象变得更Pythonic化。您需要实现两个神奇的方法来使对象迭代:第一个魔术方法“__iter__”(注意:此处加双下划线)返回被迭代的对象,通常用在循环的开始。“__next__”返回下一个对象。
让我们快速进入一个终端,调用上面的代码:
运行将打印出来
在Python中,迭代器是只有_ _ iterator _ _ magic方法的对象。这意味着您可以访问对象中的位置,但不能遍历对象。有些对象会有魔术方法__next__而不是__iter__魔术方法,比如集合(本文后面会讨论)。对于本文,我们假设我们接触的所有东西都是迭代对象。
现在我们知道了什么是iterable对象,让我们回到map函数。Map函数允许我们将函数应用于iterable中的每一项。Map需要两个输入,即要应用的函数和iterable对象。
假设我们有一个如下的数字列表:
我们要对每个数字求平方,我们可以编写下面的代码:
在Python中,函数是惰性的。如果我们不使用“list”,这个函数将存储iterable的定义,而不是列表本身。我们需要明确地告诉Python“让它成为一个列表”供我们使用。
在Python中突然从非懒求值切换到懒求值有点奇怪。如果你更多地考虑功能性思维,而不是命令性思维,那么你最终会习惯的。
现在写一个“square(num)”这样的普通函数也不错,但是不对。我们必须定义一个完整的函数才能在map中使用它?嗯,我们可以使用lambda(匿名)函数在map中定义一个函数。
Map
lambda表达式是只有一行的函数。例如,这个lambda表达式平方一个给定的数:让我们运行它:
这看起来不像函数吗?
嗯,有点混乱,但是可以解释。我们给变量“square”赋值。这个怎么样:
告诉Python这是一个lambda函数,输入叫x,冒号后面的任何东西都是你对输入做的,它会自动返回结果。
将我们的square程序简化为一行代码,我们可以这样做:
所以在lambda表达式中,所有的参数都在左边,你想用它们做什么都在右边。有点乱。但事实是,编写只有其他函数式程序员才能阅读的代码会有一些乐趣。此外,使用一个函数并将其转换为一行代码非常酷。
Reduce
Reduce是一个将迭代变成一个东西的函数。通常,你可以在列表上使用reduce函数执行计算以将其减少到一个数字。 Reduce看起来像这样:我们经常会使用lambda表达式作为函数。
列表的乘积是每个单独的数字相乘。要做到这一点你将编写如下代码:
但是使用reduce你可以这样写:
获得相同的功能,代码更短,并且在使用函数式编程的情况下更整洁。(注:reduce函数在Python3中已不是内置函数,需要从functools模块中导入)
Filter
filter函数采用可迭代的方式,并过滤掉你在该可迭代中不需要的所有内容。通常,filter需要一个函数和一个列表。它将函数应用于列表中的每一项,如果该函数返回True,则不执行任何操作。如果返回False,则从列表中删除该项。
语法如下:
让我们看一个小例子,没有filter我们会写:
使用filter,可以这样写:
Python作为一门不断发展与普及的语言,还在不断更新中。在学习时,建议找一些学习伙伴一起来学习和讨论,效果更佳。如果想学习Python,欢迎加入Python学习交流群(627012464),一起督促,一起学习。里面有开发工具,很多干货和技术资料分享!
高阶函数
高阶函数可以将函数作为参数并返回函数。一个非常简单的例子如下:第二个返回函数的例子:
开头我说过纯函数式编程语言没有变量。更高阶的函数使这变得更容易。
Python中的所有函数都是一等公民。一等公民被定义为具有以下一个或多个特征:
在运行时创建
在数据结构中分配变量或元素
作为函数的参数传递
作为函数的结果返回
Python中的所有函数都可以用作高阶函数。
Partial application
Partial application(也称为闭包)有点奇怪,但非常酷。您可以在不提供所需的所有参数的情况下调用函数。让我们在一个例子中看到这一点。我们想要创建一个函数,它接受2个参数,一个基数和一个指数,并返回指数幂的基数,如下所示:现在我们想要一个专用的平方函数,使用幂函数计算出数字的平方:
这有效,但如果我们想要一个立方体功能呢?或者求四次方的功能呢?我们可以继续写下它们吗?好吧,你可以。但程序员很懒的。如果你一遍又一遍地重复同样的事情,这表明有一种更快的方法来加快速度,这将使你不再重复。我们可以在这里使用闭包。让我们看一个使用闭包的square函数的示例:
是不是很酷!我们可以只使用1个参数来调用需要2个参数的函数。
我们还可以使用一个循环来生成一个幂函数,该函数实现从立方体一直到1000的幂。
函数式编程不是pythonic
您可能已经注意到了,我们想要在函数式编程中做的很多事情都围绕着列表。除了reduce函数和闭包之外,您看到的所有函数都会生成列表。 Guido(Python之父)不喜欢Python中的函数式,因为Python已经有了自己生成列表的方法。如果你在Python的交互环境下写入”import this“,你将会得到:
这是Python之禅。这是一首关于Pythonic意味着什么的诗。我们想要涉及的部分是:
There should be one — and preferably only one — obvious way to do it.(应该尽量找到一种,最好是唯一一种明显的解决方案)
在Python中,map和filter可以执行与列表推导(下面讨论)相同的操作。这打破了Python之禅的一个规则,因此函数式编程的这些部分不被视为“pythonic”。
另一个话题是Lambda。在Python中,lambda函数是一个普通函数。 Lambda是语法糖。这两种说法是等价的。
普通函数可以执行lambda函数可以执行的所有操作,但它不能以相反的方式工作。 lambda函数不能完成普通函数可以执行的所有操作。
这是一个简短的论证,为什么函数式编程不能很好地适应整个Python生态系统。你可能已经注意到我之前提到了列表推导,我们现在将讨论它们。
列表推导
前面,我提到过你可以用map或filter做的任何事情,你可以用列表推导。列表推导是一种在Python中生成列表的方法。语法是:让我们对列表中的每个数字进行平方,例如:
我们可以看到如何将函数应用于列表中的每一项。我们如何应用filter呢?看看前面的代码:
我们可以将其转换成一个列表推导,像这样:
列表支持if这样的语句。您不再需要将一百万个函数应用于某些东西以获得您想要的东西。事实上,如果你想尝试生成某种列表,那么使用列表推导看起来会更清晰,更容易。如果我们想要将列表中每个0以下的数字平方怎么办?有了lambda,map和filter你会写:
这似乎很长很复杂。通过列表推导,它只是:
列表推导仅适用于列表。map,filter适合任何可迭代的对象,那么这有什么用呢?你可以对你遇到的任何可迭代对象使用任何推导。
其他推导
你可以为任何可迭代对象创建一个推导。可以使用推导生成任何可迭代的对象。从Python 2.7开始,您甚至可以生成字典(hashmap)。
如果它是可迭代的,则可以生成它。让我们看一下最后一组的例子。
set是一个元素列表,在该列表中没有元素重复两次。
set中的元素没有顺序。
您可能会注意到set(集合)与dict(字典)具有相同的花括号。 Python非常聪明。根据你是否为dict提供值,它会知道你是在写dict推导还是set推导。
推荐学习:python教程以上就是一起来分析Python函数式编程的详细内容,更多请关注盛行IT软件开发工作室其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。