前言

在本文中,您将了解什么是函数范型,以及如何在Python中使用函数式编程。在Python中,函数式编程中的map和filter可以做与列表相同的事情。这打破了Python的禅宗规则之一,因此函数式编程的这些部分不被认为是“Python式的”。但是由于函数式编程高阶编程​的必经之路,所以我们需要了解甚至熟练掌握​。​

命令范式和函数范式

我们先对比一下编程中的命令范式两个概念:

在命令式范式中,您通过给计算机一个任务序列来完成任务,然后它执行这些任务。在执行它们时,它可以改变状态。例如,假设你一开始把A设为5,然后你改变A的值,你有变量,在这个意义上,变量内部的值是变化的。

在函数范型中,你不告诉计算机要做什么,而是告诉它是什么。例如:一个数的最大公约数是多少,从1到n的乘积是多少,等等。因此,变量不能改变。一旦你设置了一个变量,它就会一直保持这种状态(注意,在纯函数语言中它们不被称为变量)。所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

让我们来看一个典型Python代码的例子:

a = 3def some_func():    global a    a = 5some_func()print(a)

这段代码的输出是5。在函数范型中,改变变量是一个大禁忌,而让函数影响它们范围之外的东西也是一个大禁忌。函数唯一能做的就是计算并返回结果。

现在你可能会想:“没有变量,就没有副作用?”这有什么好处呢?”

如果一个函数使用相同的参数被调用两次,那么它肯定会返回相同的结果。因为函数没有副作用,如果你正在构建一个计算的程序,你可以加速这个程序。如果程序知道func(2)等于3,我们可以将其存储在一个表中。这可以防止程序在我们已经知道答案的情况下重复运行相同的函数。

Map

为了理解map,让我们首先看看什么是iterables。iterable是任何可以迭代的东西。通常这些是列表或数组,但是Python有许多不同类型的迭代器。您甚至可以创建自己的对象,这些对象可以使用Python中魔法方法进行迭代。这里有两个方法:

class Counter:    def __init__(self, low, high):        # set class attributes inside the magic method __init__        # for "inistalise"        self.current = low        self.high = high    def __iter__(self):        # first magic method to make this object iterable        return self        def __next__(self):        # second magic method        if self.current > self.high:            raise StopIteration        else:            self.current += 1            return self.current - 1

“魔法方法是python内置方法,不需要主动调用,存在的目的是为了给python的解释器进行调用,几乎每个魔法方法都有一个对应的内置函数,或者运算符,当我们对这个对象使用这些函数或者运算符时就会调用类中的对应魔法方法,可以理解为重写内置函数。”

第一个神奇的方法是用“__ iter__”返回迭代对象,通常在循环开始时使用。

如果我们运行:

for c in Counter(3, 8):    print(c)

那么将会输出:

345678

在Python中,迭代器是一个对象,它只有一个简单的魔法方法。这意味着您可以访问对象中的位置,但不能遍历对象。有些对象将使用方法__next__,如上面代码中第二个例子。

现在我们知道了什么是可迭代对象,让我们回到map函数。map函数允许我们将一个函数应用到iterable中的每个项。通常,我们希望对列表中的每一项都应用一个函数,但是要知道对于大多数迭代器来说都是可能的。Map接受两个输入,即要应用的函数和可迭代的对象:

map(function, iterable)

假设我们有一个列表:

[1, 2, 3, 4, 5]

我们希望将列表中的每一个数字进行平方,那么可以这么写代码:

x = [1, 2, 3, 4, 5]def square(num):    return num*numprint(list(map(square, x)))

Python中的函数是惰性的。如果我们代码中不包含“list()”,函数将存储迭代的定义,而不是一个列表。我们需要显式地告诉Python“将这个转换为一个列表”,以便我们使用它。

现在写一个像“square(num)”这样的普通函数很好,但是它看起来不太对。我们必须定义一个完整的函数才能在map中使用一次?我们可以使用lambda(匿名)函数在map中定义一个函数。

lambda 表达式

lambda表达式是一个单行函数。举个例子,这个lambda表达式对给定的一个数字求平方:

square = lambda x: x * x

运行程序:

>>> square(3)9

告诉Python这是一个lambda函数,输入被称为x,冒号后面的内容就是你对输入的操作,它会自动返回结果。

现在我们可以将上面的程序简化:

x = [1, 2, 3, 4, 5]print(list(map(lambda num: num * num, x)))

Reduce

Reduce是一个函数,它把一个可迭代的东西变成一个东西。通常,您在一个列表上执行计算以将其缩减为一个数字。Reduce是这样的:

reduce(function, list)

我们可以(通常也会)使用lambda表达式作为函数。

列表的乘积是每一个单独的数字相乘。要做到这一点,你可以:

product = 1x = [1, 2, 3, 4]for num in x:    product = product * num

但是使用reduce你可以这样写:

from functools import reduceproduct = reduce((lambda x, y: x * y),[1, 2, 3, 4])

Filter

filter函数接受一个iterable并过滤掉在该iterable中不需要的所有东西。

filter通常接受一个函数和一个列表。它将函数应用于列表中的每一项,如果该函数返回True,则不执行任何操作。如果返回False,则从列表中删除该项目。

语法如下:

filter(function, list)

让我们看看一个小例子,没有过滤器,我们会写:

x = range(-5, 5)new_list = []for num in x:    if num < 0:        new_list.append(num)

有了过滤器,这就变成:

x = range(-5, 5)all_less_than_zero = list(filter(lambda num: num < 0, x))

高阶函数

高阶函数可以将函数作为参数并返回函数。一个非常简单的例子如下:

def summation(nums):    return sum(nums)def action(func, numbers):    return func(numbers)print(action(summation, [1, 2, 3]))

partial application

部分应用程序(也称为闭包)有点奇怪,但是非常酷。您可以调用一个函数而不提供它需要的所有参数。我们来看一个例子。我们想要创建一个函数,它有两个参数,一个底数和一个指数,并返回底数的指数次方,就像这样:

def power(base, exponent):  return base ** exponent

现在我们想要一个专门的平方函数,用幂函数求出一个数的平方:

def square(base):  return power(base, 2)

这是可行的,但如果我们想要一个立方体函数呢?或者是函数的4次方?我们能一直写下去吗?嗯,你可以。但是程序员很懒。如果你一遍又一遍地重复同样的事情,这是一个信号,表明有一种更快的方法可以加快速度,让你不再重复。我们可以在这里使用部分应用程序。让我们看一个例子的平方函数使用部分应用程序:

from functools import partial​square = partial(power, exponent=2)print(square(2))

这是不是很酷!我们可以调用需要两个参数的函数,只需使用一个参数就可以告诉Python第二个参数是什么。

参考:https://medium.com/hackernoon/learn-functional-python-in-10-minutes-to-2d1651dece6f

less 函数_Python中的函数式编程教程,学会用一行代码搞定所有内容相关推荐

  1. table中加表单元素每行怎么验证_Validform 一行代码搞定整站的表单验证 - 文章

    Validform 一行代码搞定整站的表单验证,为什么能如此方便?插件的核心思想就是把所有的验证条件及验证提示信息绑定到每个表单元素,让验证代码在执行时只是核对表单下各元素的值是否跟绑定的验证条件相符 ...

  2. Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0

    Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0 之前所有的项目都有一个将崩溃日志写入到sd卡的工具类,然后每次项目新建都从老项目copy过来,后来慢慢 ...

  3. python文字提取关键信息_Python提取图片中的文字信息,腾讯内部技术,一行代码搞定!...

    用过手机QQ就知道,点击一个图片会弹出一个小功能,那就是提取图片中的文字.非常方便实用,那么很难实现吗? 利用Python提取图片中的文字信息,只需要一行代码就能搞定! 当然,这是吹牛皮的,但是真正的 ...

  4. Tensorflow快餐教程(1) - 30行代码搞定手写识别

    摘要: Tensorflow入门教程1 去年买了几本讲tensorflow的书,结果今年看的时候发现有些样例代码所用的API已经过时了.看来自己维护一个保持更新的Tensorflow的教程还是有意义的 ...

  5. 我不会编程,但“自主可控”的红芯浏览器被我用一行代码搞定

    原文: 嘶吼RoarTalk(ID:i_4hou) 作者:不会编程的小编 8月15日,红芯时代科技有限公司公司宣布获得2.5亿融资,其产品之一是拥有"中国首个自主创新智能浏览器内核" ...

  6. python炫酷可视化_Python 一行代码搞定炫酷可视化,你需要了解一下 Cuffl

    前言 学过Python数据分析的朋友都知道,在可视化的工具中,有很多优秀的三方库,比如matplotlib,seaborn,plotly,Boken,pyecharts等等.这些可视化库都有自己的特点 ...

  7. 如何把python可视化到前端_Python一行代码搞定炫酷可视化,就用这个工具!

    学过Python数据分析的朋友都知道,在可视化的工具中,有很多优秀的三方库,比如matplotlib,seaborn,plotly,Boken,pyecharts等等.这些可视化库都有自己的特点,在实 ...

  8. Spring Boot 中一行代码搞定Http请求!

    在Java的世界中,Http客户端之前一直是Apache家的HttpClient占据主导,但是由于此包较为庞大,API又比较难用,因此并不使用很多场景.而新兴的OkHttp.Jodd-http固然好用 ...

  9. vb.net读取excel并写入dgv_读取PDF中的表格写入EXCEL?30行代码搞定

    办公自动化系列+1 现在,各类数据分析的书籍,都可以在网上找到PDF版本: 同时,百度文库.各类数据统计文库.行业研究等众多论文报告,是通过PDF的形式去展示输出的: 但是,令人都头疼的是,各类数据分 ...

最新文章

  1. ldconfig提示is not a symbolic link警告的去除方法
  2. swift5自定义构造函数和自定义变量报required init?(coder: NSCoder) { fatalError(“init(coder:) has not bee错问题
  3. Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式)介绍
  4. 为何 Canvas 内元素动画总是在颤抖?
  5. java实现逾期提醒_信用卡逾期后的5个阶段 你都知道吗?
  6. 贪心法——LeetCode376 摆动序列
  7. OSAL 添加一个LED任务
  8. dtft变换的性质_dtft(dtft和dft的关系区别)
  9. 16 Three.js 游戏操作案例
  10. python的turtle的画太阳花(简洁和经典)
  11. 候鸟算法在其他问题中应用时需要修改的代码
  12. linux系统分区表修复
  13. Linux命令 - /etc/passwd文件详解
  14. Unity小地图的实现
  15. python编写opencv-OpenCV官方教程中文版(for Python)pdf+自己编写的全套目录
  16. Pikachu靶场之(XSS盲打)
  17. R语言与数据分析之三:分类算法1
  18. c语言 char* 参数,深入理解c语言中两级指针(char **pptr)的参数的用法
  19. ggplot2: post-hoc + 森林图
  20. n维椭球体积公式_【“数”你好看】点到直线与面的距离公式

热门文章

  1. 腾讯电脑管家13内测版官方下载地址
  2. 百度云虚拟机 隐藏index.php,wamp server虚拟主机设置index.php隐藏(入口文件隐藏)
  3. anaconda和vscode配置python_vscode配置anaconda3的方法步骤
  4. python 发送邮件正文字体设置_python 文字 坐标python smtplib模块发送SSL/TLS安全邮件实例...
  5. java dump分析工具_Java虚拟机详解(八)------虚拟机监控和分析工具(2)——可视化...
  6. vim 的tabnew带来的惊喜-建立多标签
  7. python无法识别vim中文代码
  8. xml解析 只有节点属性 android,and android:解析xml,一个节点标签中,有多个属性,怎样解析?...
  9. java填空题 在非静态成员方法中_Java学习(四): 类的使用
  10. php入门的ppt,php学习 字符串课件