函数式编程
一.简介
在Python中,函数是一等对象。
一等对象一般都会具有如下特点:
- 对象是在运行时创建的
- 能赋值给变量或作为数据结构中的元素
- 能作为参数传递
- 能作为返回值返回
二.高阶函数
1.将函数作为参数传递
高阶函数至少要符合以下两个特点中的一个:
- 接收一个或多个函数作为参数
- 将函数作为返回值返回
①取列表中所有的偶数
# 高阶函数
# 将函数作为参数,或者将函数作为返回值进行返回
# 定义一个函数,可以将指定一个列表中的偶数取出,并放进一个新的列表
# 创建一个列表
old_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 创建一个筛选列表中偶数的函数
# 高阶函数
# 将函数作为参数,或者将函数作为返回值进行返回
# 定义一个函数,可以将指定一个列表中的偶数取出,并放进一个新的列表
# 创建一个列表
old_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 创建一个筛选列表中偶数的函数
def fn1(old_list):
"""
这是一个筛选列表中偶数的函数
:param old_list: 源列表
:return: 返回筛选后的新列表
"""
# 创建一个新列表
new_list = []
# 遍历筛选旧列表
for num in old_list:
if num % 2 == 0:
new_list.append(num)
# 返回一个新列表
return new_list
# 调用fn1函数
print(fn1(old_list))
help(fn1)
②不确定抽取列表中什么类型的数字
# 创建一个列表
old_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 创建一个函数,判断一个数字是否为偶数
def fn2(num):
if num % 2 == 0:
return True
return False
# 创建一个函数,判断一个数字是否大于5
def fn3(num):
if num > 5:
return True
return False
# 创建一个筛选列表中指定类型数字的函数
def fn1(old_list,fn):
"""
这是抽取指定列表中指定类型数据的函数
:param old_list: 旧列表
:param fn: 抽取数据的依据
:return: 返回的新列表
"""
# 创建一个新列表
new_list = []
# 遍历筛选旧列表
for num in old_list:
if fn(num):
new_list.append(num)
# 返回一个新列表
return new_list
# 调用fn1函数,抽取指定列表中大于5的数
print(fn1(old_list,fn3))
print('#'*40)
# 调用fn1函数,抽取指定列表中的偶数
print(fn1(old_list,fn2))
# Python内置函数filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中
# 参数:
# 1.函数,根据该函数来过滤序列(可迭代的结构)
# 2.序列,需要过滤的序列(可迭代的结构)
# 返回值
# 过滤后的新序列(可迭代的结构)
r = filter(fn2,old_list)
print('r =',list(r))
③匿名函数,filter()函数
# 匿名函数,lambda表达式通常用来创建简单的函数
# 语法: lambda 参数列表 : 返回值
# 创建一个判断一个数是否是3的倍数的函数
# 普通函数
def fn4(num):
return num % 3 == 0
print(list(filter(fn4,old_list)))
# lambda函数
r = filter(lambda num : num % 3 == 0 , old_list)
print(list(r))
④map()函数
# map()函数可以将可迭代对象中的元素按照指定规则进行改变
# 将列表中的元素都加1
r = map(lambda num : num + 1 , old_list)
print(list(r))
⑤sort()函数
# sort()函数用来对列表中的元素进行排序
# sort()函数默认是直接比较列表中的元素的大小
# 但是,在sort()函数中,还可以接收一个关键字:key
# key需要一个函数作为参数,当设置了key这个关键字后,每次都会以列表中的一个元素来作为参数来调用
# 函数,并且使用该函数的返回值来进行比较
old_list = ['a','bc','c','ddd','e']
# 默认比较
old_list.sort()
print(old_list) # ['a', 'bc', 'c', 'ddd', 'e']
# 设置key(函数为len函数,用于获取元素的长度)
old_list.sort(key=len)
print(old_list) # ['a', 'c', 'e', 'bc', 'ddd']
# key关键字的另一用法
# 一般情况下,下面的列表因为既有数字又有字符串,所有不能直接进行排序
old_list = [1,'a','b',3,6,'er']
# 可以如下处理进行排序
old_list.sort(key=str)
print(old_list) # [1, 3, 6, 'a', 'b', 'er']
⑥sorted()
# sorted()函数,和sort()的用法基本一致,但是sorted()可以对任意的序列进行排序
# 并且使用sorted()进行排序,不会影响原来的对象,而是返回一个新的对象
old_list = [2,'4',6,'13',3,4,56,12]
new_list = sorted(old_list,key=int)
print('排序前:',old_list) # 排序前: [2, '4', 6, '13', 3, 4, 56, 12]
print('排序后:',new_list) # 排序后: [2, 3, '4', 4, 6, 12, '13', 56]
2.将函数作为返回值进行传递(闭包)
将函数作为返回值返回,也是一种高阶函数。
这种高阶函数,也称之为闭包,通过闭包可以创建一些只有当前函数才能访问的变量。
def fn1():
a = 10
# fn1()函数的内部再定义一个函数
def fn2():
print('我是fn2', a)
# 将fn2函数作为返回值返回
return fn2
# 调用fn1函数
result_function = fn1()
# 一般情况下,全局环境是不能获取局部变量a的值的,但是通过闭包可以实现
result_function() # 我是fn2 10
运用:
# 运用:求多个数的平均值
# 一般写法
nums = [1, 2, 3, 4, 6, 7, 12]
print(sum(nums) / len(nums)) # 5.0
# 但是现在需要一边向列表添加值,一边计算平均值
# 新建一个空列表
nums = []
def average(num):
# 向空列表中添加num
nums.append(num)
# 计算平均值
average_value = sum(nums) / len(nums)
return average_value
# 调用average函数
print('数据为:', nums, ',平均值为:', average(1)) # 数据为: [1] ,平均值为: 1.0
print('数据为:', nums, ',平均值为:', average(3)) # 数据为: [1, 3] ,平均值为: 2.0
# 但是,当前这个nums列表为全局变量,会被其他程序进行修改
def average2():
nums = []
def average(num):
# 向空列表中添加num
nums.append(num)
# 计算平均值
average_value = sum(nums) / len(nums)
return average_value
return average
average_fn = average2()
print(average_fn(10)) # 10.0
print(average_fn(20)) # 15.0
总结:
形成闭包的要件:
- 函数嵌套
- 将内部函数作为返回值进行返回
- 内部函数必须要使用到外部函数的变量
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)