AI算法工程师 | 02人工智能基础-Python基础(六)函数式编程

Python基础语法之 函数式编程

函数式编程特点之一:既允许把函数本身作为参数传入另一个函数,又允许返回一个函数。

一、高阶函数

高阶函数

  • 概念:高阶函数 ☞ 是 不仅可以传递变量,还可以传递函数 的函数(高阶函数又称面向对象编程)
  • 区分:
    ① 面向函数编程:☞ 把函数传来传去,函数是第一要素
    ② 面向对象编程:☞ 把对象传来传去,对象是第一要素

示例:

  • 知识补充 —— 传参:不仅可传值,还可传序列集合
myseq = [123, 45.67, -6.2e8]  # e8:10的八次方

def mytest(num):
    return num*2

mytest(10)
mytest(myseq)
[123, 45.67, -620000000.0, 123, 45.67, -620000000.0]
  • 示例:高阶函数(变量可以指向函数)
myseq = [123, 45.67, -6.2e8]

def convert(func, seq):  # 把函数作为参数传入
    print('转换序列中的数值,要它们统一为一样的数值类型')
    return [func(eachNum) for eachNum in seq]

print(convert(int, myseq))     # 效果:转为 int 类型
print(convert(float, myseq))   # 效果:转为 float 类型
print(convert(mytest, myseq))  # 效果:调用 mytest 函数,使得每个数 乘以 2
转换序列中的数值,要它们统一为一样的数值类型
[123, 45, -620000000]
转换序列中的数值,要它们统一为一样的数值类型
[123.0, 45.67, -620000000.0]
转换序列中的数值,要它们统一为一样的数值类型
[246, 91.34, -1240000000.0]

把函数作为参数传入,这样的函数称为高阶函数函数式编程就是指这种高度抽象的编程范式。
Python 内建的高阶函数有:map、reduce、filter、sorted。( 内建函数:就是在 Python 中被自动加载的函数,任何时候都可使用 )

内建的高阶函数

map

map 函数:会根据提供的函数对指定序列做映射

语法格式:

map(function, iterable, ...) 

# 参数含义:
# function: 表示一个函数名 或者 None
# iterable: 可以是序列、支持迭代的容器或迭代器

示例:

  • 高阶函数 map() 的实现 f(num)=num*2
myseq = [123, 45.67, -6.2e8]
def mytest(num):
    return num*2
    
list(map(mytest, myseq))  # 将 map 对象转成 list 列表

# 代码描述
# 1. 定义了一个函数 mytest,返回某个数 乘以2 以后的结果;
# 2. 接着调用 map 函数将 myseq 序列中每个元素取出来,作为 mytest 的参数调用 mytest 函数;
# 3. 之后将结果转换为列表的形式显示。
[246, 91.34, -1240000000.0]
  • 高阶函数 map() 的传入两个列表的使用
def f(x,y):
    return x+y
list(map(f,[1,2,3,4],[10,20,30]))
[11, 22, 33]

图解 - map函数原理图:
map函数原理图

reduce

reduce 函数:会对参数迭代器中的元素进行累积

语法格式:

reduce(function, iterable) 

# 参数含义:
# function: 是一个带有【两个参数】的函数 (函数必须接收两个参数)
# iterable: 是一个迭代器对象

# 说明:
# reduce 把结果继续和序列的下一个元素做累积计算,其效果就是:
# reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

示例:

# reduce 实现 1~15的累加
from functools import reduce # 1. 在使用前需要 先导入 reduce 模块

data = list(range(1, 16))
print(data)

def my_add(a,b):  # 2. 定义一个计算两个数的和的函数
    return a+b

reduce(my_add, data) 
# 3. ∵ 在调用 reduce 函数时传入了 my_add 函数和序列 data
# ∴ 程序会把序列 data 的每个元素取出来,和上次调用后的结果作为参数再次调用 my_add 函数,最后将结果返回。
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
120

filter

filter 函数:会对指定序列执行过滤操作

  • 和 map() 类似,filter() 也接收一个函数和一个序列。
  • 和 map() 不同的是:filter() 把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。

语法格式:

filter(function, iterable) 

# 参数含义:
# function: 可以是函数名称 或者 None
# iterable: 可以是序列、支持迭代的容器或迭代器

示例:

# 使用 filter 过滤列表,删掉奇数,只保留偶数(案例:输出 1~5 中的偶数)
data = list(range(1, 6))
def my_condition(x):
    return x%2==0
    
print(list(filter(my_condition, data)))
[2, 4]

图解 - filter函数原理图:
filter函数原理图

sorted

sorted 函数:可以对 list 进行排序

示例:

# sorted 可以接收一个 key 函数来实现自定义的排序
sorted([1,3,6,-20,-70],key=abs) # 根据 abs 函数 取绝对值进行排序
[1, 3, 6, -20, -70]

二、匿名函数

在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数(使用 lambda 声明)更方便。

使用 lambda 声明函数的语法格式:

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

# arg1/arg2/arg3 为函数的参数,<表达式> 相当于函数体。
# 运算结果是:表达式的运算结果。

示例:使序列中每个元素都 乘以 2

  • 普通方式声明函数
myseq = [123, 45.67, -6.2e8]
def mytest(num):
    return num*2
    
list(map(mytest, myseq)) # 将 map 对象转成 list 列表
[246, 91.34, -1240000000.0]
  • 使用 lambda 声明一个匿名函数
# 匿名函数实现
list(map(lambda x: x*2, myseq))
[246, 91.34, -1240000000.0]

注意:匿名函数有个限制 ☞ 只能有一个表达式,不用写 return,返回值就是该表达式的结果。

三、闭包

闭包需满足的条件:

  1. 存在于嵌套关系的函数中;
  2. 嵌套的内部函数引用了外部函数的变量;
  3. 嵌套的外部函数会将内部函数名作为返回值返回。

说明:

  • 闭包可理解为一个封闭的包裹,这个包裹就是一个函数。
  • 如果调用一个函数 A,这个函数 A 返回一个函数 B,这个返回的函数 B 就叫作 闭包

示例:

  • 闭包的方式实现两数相加
# 外部函数
def func_out(num1):
	# 内部函数
    def func_in(num2):
        return num1+num2   # 引用外部函数的变量 num1
    #  返回内部函数的名称
    return func_in
f=func_out(10) # 将调用外部函数 func_out 的结果赋值给变量 f,f引用的是 func_in 函数占用的内存空间
result=f(20)  # 调用了 f 函数,实际上就是 func_in 函数
print('结果:',result)
结果: 30
  • 闭包的方式实现内容的打印
def log(func):
    def wrapper(a, b):
        func("%s和%s相约鹊桥"%(a,b))
        func("%s和%s看电影"%(a,b))
        func("%s和%s明年见"%(a,b))
    return wrapper  # 返回函数名,即:返回函数的逻辑
log(print)("牛郎", "织女")
牛郎和织女相约鹊桥
牛郎和织女看点电影
牛郎和织女明年见

程序执行过程:
程序执行过程

四、装饰器

装饰器(decorator):本质上是一个Python 函数(装饰器是一种闭包),它可以在不改动其他函数的前提下,对函数的功能进行扩充。

装饰器的语法:

@装饰器名称

# 符号“@”放在函数或类的定义行之前

示例:

def log(func):
    def wrapper():
        print("约会开始了")
        func()
        print("明年见")
    return wrapper
@log   # 等价于 my_deca = log(my_deca)
def my_deca():
    print("牛郎和织女看电影")
my_deca()
约会开始了
牛郎和织女看电影
明年见

程序执行过程分析:
程序执行过程分析

—— 说明:本文内容基于python3.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值