Python学习第四部分 函数式编程

文章目录

  • 高阶函数
  • lambda 表达式和匿名函数
  • 偏函数
  • 闭包
  • map函数
  • reduce函数
  • filter 函数
  • sorted函数

函数式编程主要学习:高阶函数、闭包closure、匿名函数、偏函数,map函数、reduce函数、filter函数、sorted函数

函数式编程是个很古老的概念,最古老的函数式编程语言Lisp,新出现的函数式编程语言比如Erlang,Scala,clojure等,热门语言Python、java、JavaScript、C++等增加了函数式编程的一些特性。

函数式编程在有些时候非常方便。

高阶函数

函数是一等公民,可以赋值、可以作为参数传递、可以作为返回值。一个函数可以接收另一个函数作为参数,就称之为高阶函数。 python内建的高阶函数有map reduce filter sorted

def test():
    print("test function run!!")
    

def test2(func,*args,**kwargs):
    print("test2 function run...")
    func(*args,**kwargs)

def test03(a,b):
    print(f"test03,{a},{b}")

a = test
#test2(a)
test2(test03,100,200)

test2 function run…
test03,100,200

lambda 表达式和匿名函数

lambda表达式可以用来声明匿名函数,只允许包含一个表达式,不能包含复杂语句。语法如下:

lambda arg1,arg2,arg3,...:<表达式>

arg1,arg2,arg3为函数的参数,表达式相当于函数体。

f= lambda a,b,c:a+b+c
print(f)
f(10+20,20,30)
f(10,20,30)

偏函数

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

print(int('12345'))

int()函数还提供额外的base参数,默认值为10。如果阐述base参数,就可以做N进制转换。

print("转换为八进制: ",int('12345',base=8))
print("转换为十六进制:",int('12345',base=16))
print("转换为十进制:",int('12345',base=10))

转换为八进制: 5349
转换为十六进制: 74565
转换为十进制: 12345

可以利用functools.partial创建偏函数

import functools
int2=functools.partial(int,base=2)

print(int2('1010101'))
print(int2('1010101',base=10))

85
1010101

闭包

闭包的两部分,函数本身、外部函数的局部变量
根据字面意思,可以形象地把闭包理解为一个封闭的包裹,这个包裹就是一个函数。当然,还有函数内部对应的逻辑,包裹里面的东西就是自由变量(外部函数的局部变量),自由变量可以随着包裹到处游荡。

局部变量:如果名称绑定再一个代码块中,则为该代码块的局部变量,除非声明为`nonlocal或global`
全局变量:如果模块绑定在模块层级,则为全局变量
自由变量:如果变量在一个代码块中被使用但不是在其中定义,则为自由变量

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

闭包的特点:存在内外层函数嵌套的情况;内层函数应用了外层函数的变量或参数(自由变量);外层函数把内层的这个函数本身当做返回值进行返回。

def outer():
    print("outer")
    a=3
    
    def inner():
        print("inner")
        nonlocal a # 闭包是由于函数内部使用了函数外部的变量,这个函数对象不销毁,则外部函数的局部变量也不会被销毁
        print(f"a:{a}")
   
    return inner

a = outer()
 
print("---------")
a()

outer


inner
a:3

闭包的作用:
隐藏变量,避免全局污染;可以读取函数内部的变量;
但是:闭包使用不当,导致变量不会被垃圾回收机制回收,造成内存消耗;也可能造成内存泄露的问题。

示例 使用全局变量实现变量自增,但是污染了其他程序

a = 10 
def add():
    global a
    a += 1
    print("a:",a)

def print_ten():
    if a == 10 :
        print("ten!!")
    else:
        print("全局变量a,不等于10")
add()
add()
add()
add()
print_ten()

a: 11
a: 12
a: 13
a: 14
全局变量a,不等于10

示例 未污染,但是未实现自增

a = 10 
def add():
    a=10
    a += 1
    print("a:",a)

def print_ten():
    if a == 10 :
        print("ten!!")
    else:
        print("全局变量a,不等于10")
add()
add()
add()
add()
print_ten()

a: 11
a: 11
a: 11
a: 11
ten!!

通过自由变量,实现递增,也不污染其他程序

a = 10 
def add():
    a=10
    def incrment():
        nonlocal a
        a += 1
        print("a:",a)
    return incrment

def print_ten():
    if a == 10 :
        print("ten!!")
    else:
        print("全局变量a,不等于10")
incrment=add()
incrment()
incrment()
incrment()
print_ten()

a: 11
a: 12
a: 13
ten!!

案例 用闭包实现不修改源码添加功能

def outfunc(func):
    
    def infuc():
        print("日志记录...")
        func()
    return infuc

def fun1():
   
    print("使用功能1")

def fun2():
    print("使用功能2")
    

fun1=outfunc(fun1)
fun1()

fun2=outfunc(fun2)
fun2()

map函数

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

# 自己编写实现
def f(x):
	return x*x
L=[]
for i in [1,2,3,4,5,6,7,8,9]:
	L.append(f(i))
print(L)

# map实现
L=map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])
print(list(L))
# 或者
L=map(f,[1,2,3,4,5,6,7,8,9])
print(list(L))

[1, 4, 9, 16, 25, 36, 49, 64, 81]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
[1, 4, 9, 16, 25, 36, 49, 64, 81]

reduce函数

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

reduce(f,[x1,x2,x3,x4])= f(f(f(x1,x2),x3),x4)

示例:

from functools import reduce

def add(x,y):
    return x+y

m=[1,2,3,4,5,6,7,8,9,10]
print(reduce(add, m)) ## 结果是55 

filter 函数

内置函数flter() 用于过滤序列。filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。true 保留,false 丢弃

def is_odd(n):
    return n%2==1

L=filter(is_odd,[1,2,3,4,5,6])
print(list(L))  ## 结果是 [1, 3, 5]

sorted函数

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

示例 sorted对list进行排序

sorter1 = sorted([1,2,3,-1,-20,34])
print(sorter1 ) # 升序排序

sorted函数也是个高阶函数,还可以接收一个key实现自定义排序

示例 自定义排序

sorter1 = sorted([1,2,3,-1,-20,34])
print(sorter1 ) # 升序排序

sorter2 = sorted([1,2,3,-1,-20,34],key=abs)
print(sorter2 ) # 绝对值排序

sorter3 = sorted([1,2,3,-1,-20,34],key=abs,reverse=True) #绝对值排序,反序
print(sorter3 )

[-20, -1, 1, 2, 3, 34]
[1, -1, 2, 3, -20, 34]
[34, -20, 3, 2, 1, -1]

def custom_sorted(st1,st2):
    if st1.age<st2.age:
        return -1
    if st1.age>st2.age:
        return 1
    return 0

st1=Stutent(13,'zhangsan')
st2=Stutent(14,'lisi')
st3=Stutent(15,'wangwu')
st4=Stutent(12,'zhaoliu') 

stdent_list=sorted([st1,st2,st3,st4],key=cmp_to_key(custom_sorted)) 

for stu in stdent_list:
    print(stu.name,stu.age)

zhaoliu 12
zhangsan 13
lisi 14
wangwu 15

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/608449.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎么用AI软件设计字体

一 工具准备 软件&#xff1a;Adobe illustrator 如下网盘自取 链接&#xff1a;https://pan.baidu.com/s/1hlImpN4QlsSkOLLUxINOGA 提取码&#xff1a;love 安装的时候看不全界面&#xff0c;多按几下tab键就能看到按钮。 直接找一款喜欢的字体修改&#xff0c;字体包如下…

物联网网关制造生产全流程揭秘!

如果您正有开发和定制物联网网关的计划&#xff0c;找一个专业的物联网设备厂商协助您制造生产物联网网关可以节省大量时间和成本&#xff0c;可以让您能专注于当前核心业务&#xff0c;而无需将精力过多地投入到自己不擅长的领域。 当然&#xff0c;了解物联网网关的测试和制…

基于JSP动漫论坛的设计与实现(二)

目录 3. 系统开发环境及技术介绍 3.1 开发环境 3.2 开发工具 3.2.1 MyEclipse8.5 3.2.2 MySql 3.3 相关技术介绍 3.3.1 JSP技术简介 3.3.2 JDBC技术技术简介 3.3.3 MVC模式与Struts框架技术 4. 总体设计 4.1 系统模块总体设计 4.1.1 普通用户模块设计 4…

数据库的使用基础-SQL语句

一、在MYSQL中&#xff0c;创建数据库&#xff0c;语法如下&#xff1a; CREATE DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>] [[DEFAULT] COLLATE <校对规则名>];[ ]中的内容是可选的。语法说明如下&#xff1a; <数据库…

LeetCode738:单调递增的数字

题目描述 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 332 代码 class Solution { public:int monotoneIncreasingDigits(…

Imagine Flash、StyleMamba 、FlexControl、Multi-Scene T2V、TexControl

本文首发于公众号&#xff1a;机器感知 Imagine Flash、StyleMamba 、FlexControl、Multi-Scene T2V、TexControl You Only Cache Once: Decoder-Decoder Architectures for Language Models We introduce a decoder-decoder architecture, YOCO, for large language models, …

QT---day4事件

1、思维导图 2、 头文件 #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include<QIcon> //图标类 #include<QLabel> //标签类 #include<QMovie> //动图类 #include<QLineEdit> //行编辑器类 #include<QPushButton> //按钮…

AJAX知识点(前后端交互技术)

原生AJAX AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML&#xff0c;通过AJAX可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff1a;无需刷新就可获取数据。 AJAX不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用的新方式 …

【进程等待】阻塞等待 | options非阻塞等待

目录 waitpid 阻塞等待 options&非阻塞等待 pid_t返回值 阻塞等待VS非阻塞等待 waitpid 回顾上篇&#xff1a; pid_ t waitpid(pid_t pid, int *status, int options); 返回值&#xff1a; 当正常返回的时候waitpid返回收集到的子进程的进程ID&#xff1b;如果设置了…

C++容器之vector类

目录 1.vector的介绍及使用1.1vector的介绍1.2vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector 空间增长问题1.2.4 vector 增删查改1.2.5vector 迭代器失效问题1.2.6 vector 在OJ中的使用。 2.vector深度剖析及模拟实现2.1 std::vector的核心框架接口…

金三银四面试题(二十五):策略模式知多少?

什么是策略模式 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;旨在定义一系列算法&#xff0c;将每个算法封装到一个独立的类中&#xff0c;使它们可以互换。策略模式让算法的变化独立于使用它们的客户端&#xff0c;使得客户端可以根据…

车载测试系列:入行车载测试分享

车载测试前景如何&#xff1f; 软件定义汽车时代的发展趋势&#xff0c;随着控制器自主开发力度的加强&#xff0c;作为V流程中必备环节&#xff0c;车载测试工程师岗位需求会越来越多&#xff1b;控制器集成化&#xff0c;功能集成程度越来越高&#xff0c;对于测试工程师的知…

3. 初探MPI——(非阻塞)点对点通信

系列文章目录 初探MPI——MPI简介初探MPI——&#xff08;阻塞&#xff09;点对点通信初探MPI——&#xff08;非阻塞&#xff09;点对点通信初探MPI——集体通信 文章目录 系列文章目录前言一、Non-blocking communications1.1 Block version1.2 Non-blocking version 二、准…

思维导图软件哪个好?盘点这5款好用的工具!

思维导图作为一种有效的思维工具&#xff0c;在日常生活和工作中扮演着越来越重要的角色。无论是学习、工作规划&#xff0c;还是项目管理&#xff0c;思维导图都能帮助我们更好地组织思路&#xff0c;提升工作效率。然而&#xff0c;市面上众多的思维导图软件让人眼花缭乱&…

软件系统工程建设全套资料(交付清单)

软件全套精华资料包清单部分文件列表&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求调查单&#xff0c;用户需求说明书&#xff0c;概要设计说明书&#xff0c…

C++类和对象(4)

目录 1.初始化列表 2.单参数里面的隐式类型转换 3.多参数的隐式类型转换 4.匿名对象 1.初始化列表 &#xff08;1&#xff09;首先看一下初始化列表具体是什么&#xff1f; 这个就是初始化列表的具体形式&#xff0c;对&#xff0c;你没有看错&#xff0c;这个初始化列表里…

python:画折线图

import pandas as pd import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties# 设置新宋体字体的路径 font_path D:/reportlab/simsun/simsun.ttf# 加载新宋体字体 prop FontProperties(fnamefont_path)""" # 读取 xlsx 文件 d…

【投资必看】充电桩加盟合作哪家好,充电桩厂家合作模式一般有哪些?

随着新能源汽车行业的蓬勃发展&#xff0c;充电桩作为关键的基础设施&#xff0c;其市场需求日益增长。对于有意进入这一行业的投资者来说&#xff0c;了解和选择适合的合作模式至关重要。充电桩厂家的合作模式一般有哪些&#xff0c;本文将从设备销售和投资运营两个维度进行讨…

容灾演练双月报|郑大一附院数据级容灾演练切换

了解更多灾备行业动态 守护数字化时代业务连续 目录 CONTENTS 01 灾备法规政策 02 热点安全事件 03 容灾演练典型案例 01 灾备法规政策 3月19日&#xff0c;工信部发布《工业和信息化部办公厅关于做好2024年信息通信业安全生产和网络运行安全工作的通知》。明确提出“…

官宣:vAsterNOS正式发布!开放网络操作系统免费试用!

近期&#xff0c;vAsterNOS&#xff08;设备模拟器&#xff09;正式发布&#xff0c;可以满足用户快速了解 AsterNOS、体验实际操作、搭建模拟网络的需求&#xff0c;可运行在GNS3、EVE-NG等网络虚拟软件中。 AsterNOS 网络操作系统是星融元为人工智能、机器学习、高性能计算、…
最新文章