python命令式编程的概念,【Python】十分钟学会函数式编程
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达
本文转自:深度学习这点小事
函数式编程到底是什么?本文将详解其概念,同时分享怎样在 Python 中使用函数式编程。主要内容包括列表解析式和其他形式的解析式。函数式模型
在命令式模型中,执行程序的方式是给计算机一系列指令让它执行。执行过程中计算机会改变状态。例如,比如 A 的初始值是 5,后来改变了 A 的值。那么 A 就是个变量,而变量的意思就是包含的值会改变。
而在函数式模式中,你不需要告诉计算机做什么,而是告诉计算机是什么。比如数字的最大公约数是什么,1 到 n 的乘积是什么等等。
因此,变量是不能被改变的。变量一旦被设置,就永远保持同一个值(注意在纯粹的函数式语言中,它们不叫变量)。因此,在函数式模型中,函数没有副作用。副作用就是函数对函数外的世界做出的改变。来看看下面这段Python代码的例子:a = 3
def some_func():
global a
a = 5
some_func()
print(a)
代码的输出是 5。在函数式模型中,改变变量的值是完全不允许的,让函数影响函数外的世界也是不允许的。函数唯一能做的就是做一些计算然后返回一个值。
你可能会想:“没有变量也没有副作用?这有什么好的?”好问题。
如果函数使用同样的参数调用两次,那么我们可以保证它会返回同样的结果。如果你学过数学函数,你肯定知道这样做的好。这叫做引用透明性(referential transparency)。由于函数没有副作用,那么我们可以加速计算某个东西的程序。比如,如果程序知道 func(2)返回 3,那么可以将这个值保存在表中,这样就不需要重复运行我们早已知道结果的函数了。
通常,函数式编程不使用循环,而是使用递归。递归是个数学概念,通常的意思是“把结果作为自己的输入”。使用递归函数,函数可以反复调用自己。下面就是个使用Python定义的递归函数的例子:def factorial_recursive(n):
# Base case: 1! = 1
if n == 1:
return 1
# Recursive case: n! = n * (n-1)!
else:
return n * factorial_recursive(n-1)
函数式编程语言也是懒惰的。懒惰的意思是,除非到最后一刻,否则它们不会执行计算或做任何操作。如果代码要求计算2+2,那么函数式程序只有在真正用到计算结果的时候才会去计算。我们马上就会介绍Python中的这种懒惰。映射
要理解映射(map),首先需要理解什么是可迭代对象。可迭代对象(iterable)指任何可以迭代的东西。通常是列表或数组,但 Python 还有许多其他可迭代对象。甚至可以自定义对象,通过实现特定的魔术方法使其变成可迭代对象。魔术方法就像 API 一样,能让对象更有 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
第一个魔术方法“__iter__”(双下划线iter)返回迭代子,通常在循环开始时调用。__next__则返回迭代的下一个对象。
可以打开命令行试一下下面的代码:for c in Counter(3, 8):
print(c)
这段代码将会输出:3
4
5
6
7
8
在 Python 中,迭代器就是只实现了__iter__魔术方法的对象。也就是说,你可以访问对象中都包含的位置,但无法遍历整个对象。一些对象实现了__next__魔术方法,但没有实现__iter__魔术方法,比如集合(本文稍后会讨论)。在本文中,我们假设涉及到的一切对象都是可迭代的对象。
现在我们知道了什么是可迭代的对象,回过头来讨论下映射函数。映射可以对可迭代对象中的每个元素执行指定的函数。通常,我们对列表中的每个元素执行函数,但要知道映射其实可以针对绝大多数可迭代对象使用。map(function, iterable)
假设有一个列表由以下数字组成:[1, 2, 3, 4, 5]
我们希望得到每个数字的平方,那么代码可以写成这样:x = [1, 2, 3, 4, 5]
def square(num):
return num*num
print(list(map(square, x)))
Python中的函数式函数是懒惰的。如果我们不加“list()”,那么函数只会将可迭代对象保存下来,而不会保存结果的列表。我们需要明确地告诉Python“把它转换成列表”才能得到结果。
在Python中一下子从不懒惰的函数求值转换到懒惰的函数似乎有点不适应。但如果你能用函数式的思维而不是过程式的思维,那么最终会适应的。
这个“square(num)”的确不错,但总觉得有点不对劲。难道为了仅使用一次的map就得定义整个函数吗?其实我们可以使用lambda函数(匿名函数)。Lambda 表达式
Lambda表达式就是只有一行的函数。比如下面这个lambda表达式可以求出给定数字的平方:square = lambda x: x * x
运行下面的代码:>>> square(3)
9
你肯定在问:“参数去哪儿了?这究竟是啥意思?看起来根本不像函数啊?”
嗯,的确是不太容易懂……但还是应该能够理解的。我们上面的代码把什么东西赋给了变量“square”。就是这个东西:lambda x:
它告诉Python这是个lambda函数,输入的名字为x。冒号后面的一切都是对输入的操作,然后它会自动返回操作的结果。
这样我们的求平方的代码可以简化成一行:x = [1, 2, 3, 4, 5]
print(list(map(lambda num: num * num, x)))
有了lambda表达式,所有参数都放在左边,操作都放在右边。虽然看上去有点乱,但不能否认它的作用。实际上能写出只有懂得函数式编程的人才能看懂的代码还是有点小兴奋的。而且把函数变成一行也非常酷。归纳
归纳(reduce)是个函数,它把一个可迭代对象变成一个东西。通常,我们在列表上进行计算,将列表归纳成一个数字。归纳的代码看起来长这样:reduce(function, list)
上面的函数可以使用lambda表达式。
列表的乘积就是把所有数字乘到一起。可以这样写代码:product = 1
x = [1, 2, 3, 4]
for num in x:
product = product * num
但使用归纳,可以写成这样:from functools import reduce
product = reduce((lambda x, y: x * y),[1, 2, 3, 4])
这样能得到同样的结果。这段代码更短,而且借助函数式编程,这段代码更简洁。过滤
过滤(filter)函数接收一个可迭代对象,然后过滤掉对象中一切不需要的东西。
通常过滤接收一个函数和一个列表。它会针对列表中的每个元素执行函数,如果函数返回True,则什么都不做。如果函数返回False,则从列表中去掉那个元素。
语法如下:filter(function, list)
我们来看一个简单的例子。没有过滤,代码要写成这样:x = range(-5, 5)
new_list = []
for num in x:
python命令式编程的概念,【Python】十分钟学会函数式编程相关推荐
- python股票自动买卖视频教程_十分钟学会用Python交易股票
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 本文通过讲述 [单股票均线策略] 在 Ricequant 量化平台的实现,熟悉平台并快速入门.创建自己的量化策略代码 .难易度:入门级.从一下几点说起: ...
- python wordcloud详解_Python+wordcloud十分钟学会生成英文词云
基于python生成的wordcloud 词云在这两年一直都热门话题,如果你耐下性子花个10分钟看看这篇文章,或许你就再也不用羡慕那些会词云的人了.这不是一项高深莫测的技术,你也可以学会.快来试试吧! ...
- 虚拟局域网软件开源_玩转虚拟机,十分钟学会一台电脑安装3个操作系统
玩转虚拟机,十分钟学会一台电脑安装3个操作系统 本文目录 一.什么是虚拟机 1.普通虚拟机 2.Java虚拟机 二.虚拟机的作用 三.虚拟机的安装需求 四.常用的虚拟机软件 1.VMware虚拟机 2 ...
- 一些生活中简单可用的技能--十分钟学会,终生受益
一些日常生活中简单可用的技能 十分钟学会,终生受益 工作 学习 生活 社交 十分钟学会,终生受益 下面的文章是从知乎高赞回答中"日常生活中有哪些十分钟就能学会并可以终生受用的技能?" ...
- 十分钟学会win10系统封装之系列教程(一):在VMware Workstation虚拟机上安装win10母盘系统
关于系统封装这个话题,历来就一直受到很多小伙伴的青睐,很多同学都认为会封装系统是一件很高大上的事情,所以一直都有很多小伙伴向亦是美网络小编询问到底什么时候能出一些关于win10系统封装的教程,其实小编 ...
- java中xml的组装与解析(十分钟学会)
xml的组装与解析(十分钟学会) 一.xml的解析 话不多说直接上代码 1.引入pom依赖 // 解析xml <dependency><groupId>org.jsoup< ...
- 翻译连载 | 附录 C:函数式编程函数库-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇...
为什么80%的码农都做不了架构师?>>> 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS> ...
- 快速入门:十分钟学会Python
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
- python 嵌套数组_兴趣是最好的老师,快速入门:十分钟学会python
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
最新文章
- 极致真实感受 无边硬屏即将登场
- SQLSERVER导入导出文本文件
- Windows Server 2008怎么查看远程桌面登录日志
- FileSystemResource 和 ClassPathResource 有何区别
- 如何在VS2005下生成动态运行时库
- MFC界面UI像素设计
- vs2010学习版安装与激活
- linux系统下如何github,在Linux系统下使用Github的基本教程
- 批量修改bilibili下载视频的文件名
- mysql 基础语法3
- 微服务--应对每秒上万并发下的参数优化实战(实战经验)
- 医学影像后处理技术超详细收藏版(上)
- GitHub 小白入门
- 尚硅谷mycat2.0安装和配置
- Textpad 1.7下载
- 《你一学就会的-思维大图》读书笔记
- 刘易远:如何提升自我赋能?
- python数据导出excel_Python-将数据表中数据导出到excel
- Mysql rbo和cbo_oracle的优化——RBO和CBO简介以及optimizer_mode参数说明
- lattice 的Synplify pro综合工具,以及RTL寄存器查看