Python_函数式编程核心(高阶函数、闭包等)

函数式编程(functional programming)其实是个很古老的概念,诞生距今快60年啦!最古老的函数式编程语言Lisp新出现的函数式编程语言:比如Erlang、Scala、clojure等热门语言:Python、java、JavaScript、C++等都增加了函数式编程的一些特性。

⚠️函数式编程在某些时刻,非常方便!但不需大家二选一。⚠️我们通过一些常见的函数式编程的内容,先学习,后体会"函数式编程"。

高阶函数和内存分析函数是一等公民:

函数式编程最鲜明的特点就是:函数是一等公民(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。12一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数。3Python内建的高阶函数有map、reduce、filter、sorted

高阶函数_内存状态分析【示例】高阶函数案例:

python 复制代码
#coding=utf-8
def test1():
   print("I'm test!")
def test2(func):    # test2就是一个高阶函数
func()
print("test2 running...")
if__name__ == '__main__':
   print(test1)  # <function test1 at0x00000240A5FA3E20>
   print(type(test1)) # <class 'function'>
   a = test1   # a和test1都指向了同一个函数对象
   a()     # I'm test!
   test2(a)    #a作为参数传递给test2()

lambda表达式和匿名函数:

lambda表达式可以用来声明匿名函数。lambda函数是一种简单的、在同一行中定义函数的方法。lambda函数实际生成了一个函数对象。lambda表达式只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是函数的返回值。lambda表达式的基本语法如下:

Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。偏函数:作用就是把一个函数某些参数固定住(也就是设置默认值),返回一个新的函数,调用这个新的函数会更简单。举例如下:int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换,代码如下:print(int('12345'))但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:

假设要转换大量的二进制字符串,每次都传入int(x,base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去,现在定义一个int2函数,代码如下:

functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

闭包closure:

根据字面意思,可以形象地把闭包理解为一个封闭的包裹,这个包裹就是一个函数。当然,还有函数内部对应的逻辑,包裹里面的东西就是自由变量(外部函数的局部变量),自由变量可以随着包裹到处游荡。局部变量:如果名称绑定再一个代码块中,则为该代码块的局部变量,除非声明为nonlocal或global全局变量:如果模块绑定在模块层级,则为全局变量自由变量:如果变量在一个代码块中被使用但不是在其中定义,则为自由变量

闭包概念和第一个闭包程序我们知道,函数作用域是独立的、封闭的,外部的执行环境是访问不了的,但是闭包具有这个能力和权限。闭包是一个函数,只不过这个函数有[超能力],可以访问到另一个函数的作用域。「函数」和「自由变量」的总和,就是一个闭包。

闭包的特点:

第一,闭包是一个函数,而且存在于另一个函数当中

第二,闭包可以访问到父级函数的变量,且该变量不会销毁

【示例】一个简单的闭包:

python 复制代码
def outer():
   a = 1
   def inner():
       nonlocal a
      #闭包是由于函数内部使用了函数外部的变量。这个函数对象不销毁,则外部函数的局部变量也不会被销毁!
       print("a:",a)
       a += 1
   return inner
inn = outer()
inn()
inn()
"""
a: 1
a: 2
a: 3
a: 4
"""

闭包内存分析

闭包可以当成两个部分组成的整体:1函数2自由变量

闭包的作用作用1:隐藏变量,避免全局污染作用2:可以读取函数内部的变量同时闭包使用不当,优点就变成了缺点:缺点1:导致变量不会被垃圾回收机制回收,造成内存消耗缺点2:不恰当的使用闭包可能会造成内存泄漏的问题闭包和自由变量【示例】使用全局变量实现变量自增,但污染了其他程序

map函数:

map()函数接收两种参数,一是函数,一种是序列(可以传入多个序列),map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3,4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:

【示例】map高阶函数的使用案例

reduce位于functools模块reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)

【示例】reduce实现对一个序列求和

filter函数:

【示例】filter序列中的空字符串删掉

sorted函数排序算法,排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。1如果是数字,我们可以直接比较如果是自定义对象呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。

相关推荐
千澜空15 分钟前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
斯凯利.瑞恩22 分钟前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林
杨荧37 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰43 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
yannan2019031343 分钟前
【算法】(Python)动态规划
python·算法·动态规划
蒙娜丽宁1 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
光芒再现dev1 小时前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。1 小时前
c++多线程
java·开发语言
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript