前面我们已经总结并实践了用python获取到了数据。也介绍了python中http网络请求的几种方式,正在学习python开发语言或者对python3知识点生疏需要回顾的请点这里 ,本章主要总结了函数式编程及特点 和 python中内置的高阶函数及周边知识,方便自己查看也欢迎大家参考,谢谢。
目录
一、了解函数式编程
函数式编程的特点:
- 不是纯函数式编程:允许有变量
- 支持高阶函数:函数可以作为变量
- 支持闭包:可以返回函数
- 支持匿名函数
二、python内置的高阶函数及周边
1.把函数当作参数
顾名思义就是把一个函数当作参数使用。例如:
# abs函数把传递的数据乘以10 后返回
def abs(x):
return x*10
# 这里参数 f参数就是需要传递一个函数
def add(x, y, f):
return f(x) + f(y)
# 这里在调用add方法的时候 把上面abs函数作为参数传入
result = add(-5, 9, abs)
# 相当于 result = abs(-5) + abs(9)
print(result) # 40
2.Python的内置函数map()
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list。并通过函数 f处理list中的每个元素,map()函数会返回一个迭代器,可以依次迭代得到原来list的元素被函数f处理后的结果。
例如,对于list [9, 8, 7, 6, 5, 4, 3, 2, 1]。
如果希望把list的每个元素都作平方,就可以利用map()函数。
3.Python的内置函数reduce()
reduce()函数接收的参数和 map() 类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
在python3中,reduce()函数被收录到functools包内,需要引入functools才可以使用。
# 从functools包中引入reduce模块
from functools import reduce
# 定义一个list数组
list = [5, 4, 3, 2, 1]
# 定义当做reduce函数的参数的函数
def f(x,y):
return x*y
# 执行reduce高阶函数后打印数据
print(reduce(f, list))
其实这个计算结果是120. 其实就是list元素的乘积 5*4*3*2*1 = 120.
f(5,4) f(20,3) f(60,2) f(120,1) 就是f()函数第一次执行的结果当做下一次函数的x参数使用,返回最终结果。
reduce()还可以接收第3个可选参数,作为计算的初始值。如果把初始值设为2
# 执行reduce高阶函数后打印数据
print(reduce(f, list, 200)) #24000
4.python的内置函数filter()
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,并返回一个迭代器,可以迭代出所有符合条件的元素。
例如现在要找出10以内的奇数。
利用filter函数还可以处理空的字符串和无效数据:
# 定义要处理的数据
list = ['STR', None, '', 'rose', ' ', 'fly']
# 判断元素是否为空 为空则返回false 执行filter函数会过滤掉
def is_not_empty(s):
return s and len(s.strip()) > 0
# 过滤掉为空的数据并打印数据
for item in filter(is_not_empty, list):
print(item)
注意: s.strip()会默认删除空白字符(包括'\n', '\r', '\t', ' ')
5.Python排序函数 sorted()
Python内置的 sorted()函数可对list进行排序:
- 默认是由小到大排序列表的元素。
- 当list的每一个元素又是一个容器时,则会以第一个元素来排序 sorted()函数则按名字首字母进行了排序并返回。
如果需要按照成绩高低进行排序,需要指定排序的字段是成绩,sorted接受key参数,用来指定排序的字段,key的值是一个函数,接受待排序列表的元素作为参数,并返回对应需要排序的字段。因此,sorted()函数也是高阶函数。可接收三个参数:
print(sorted(food)) # 经过sorted函数默认排序后打印
print(sorted(food, key=k)) #传入指定按成绩排序的参数 key
print(sorted(food, key=k,reverse=True)) #reverse 设置倒序排序
6.Python返回函数
在函数内部,是可以定义子函数的。作为高阶函数,可以接受函数作为参数,其实高阶函数,除了不仅仅可以返回int、str、list、dict等数据类型,还可以返回函数。因此,可以把函数的子函数返回。
要注意的是,返回函数和返回函数值的语句是非常类似的,返回函数时,不能带小括号,而返回函数值时,则需要带上小括号以调用函数。
# 返回函数
def myabs():
return abs
# 返回函数值
def myabs(x):
return abs(x)
返回函数有很多应用,比如可以将一些计算延迟执行:
#直接计算返回list元素求和数据
# 定义函数 返回内置函数 sum()
def calc_sum(list_):
return sum(list_)
#调用函数得到list数组元素之和赋值给result
result = calc_sum([1, 2, 3, 4])
print(result) #10
如果返回一个函数,我们必须重新调用返回的函数才会执行内置函数sum,代码应该更清晰。
这样我们拿到的函数可以根据当前需求决定要不要执行,代码更灵活。
7.Python的闭包
内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。前面我们用到的例子:calc_sum(list)函数
我们没法把 lazy_sum 移到 calc_sum 的外部,因为它引用了 calc_sum 的参数 list_,像这样内层函数引用外层函数的变量(参数),然后把内层函数返回,就称为闭包。
def calc_sum(list_):
def lazy_sum():
return sum(list_)
return lazy_sum
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
8.Python的匿名函数
高阶函数可以接收函数做参数,有些时候,我们不需要显式地定义函数,直接传入匿名函数更方便。
匿名函数使用lambda定义:lambda x: x * x,就可以完成原来显式定义的f(x)函数的功能,冒号前面的x表示匿名函数的参数,后面的是一个表达式,匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。
list数组经map函数处理后返回的数据。
9.Python编写无参数的decorator
Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。
使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。
编写@log:
def log(f):
def fn(x):
print('call ' + f.__name__ + '()...')
return f(x)
return fn
#用于阶乘函数
@log
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print(factorial(10))
多个参数时:对于参数大于等于两个的就会报错, @log 写死了只含一个参数的返回函数。要让 @log 自适应任何参数定义的函数,可以利用Python的 args 和 *kwargs,保证任意个数的参数总是能正常调用:
def log(f):
def fn(*args, **kwargs):
print('call ' + f.__name__ + '()...')
return f(*args, **kwargs)
return fn
10.Python编写有参数的decorator
前面 编写 log函数时 默认打印信息print('call ' + f.__name__ + '()...')语句是固定不变的,只有函数名称可以动态打印,如果我们根据函数的重要做了区分想显示出来怎么办呢?这时,log函数本身就需要传入'INFO'或'DEBUG'这样的参数。
@log('DEBUG')
def my_func():
pass
#上面的定义翻译成高阶函数的调用
my_func = log('DEBUG')(my_func)
# 又相当于
log_decorator = log('DEBUG')
@log_decorator
def my_func():
pass
所以,带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数,相当于是在原有的二层嵌套里面,增加了一层嵌套:
def log(prefix):
def log_decorator(f):
def wrapper(*args, **kw):
print('[{}] {}()...'.format(prefix, f.__name__))
return f(*args, **kw)
return wrapper
return log_decorator
@log('DEBUG')
def test():
pass
test()
11.Python的偏函数
当一个函数有很多参数时,调用者就需要提供多个参数。如果减少参数个数,就可以简化调用者的负担。
偏函数指的就是“创建一个调用另外一个部分参数或变量已经预置的函数”的函数的用法,functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义。
int()函数将字符串转换成整数,下面代码int默认是按照十进制去转换的.即默认参数为10,如果传入base参数,就可以做 N 进制的转换:
# int()函数将字符串转换成整数
age1 = int('20',base=10)
age2 = int('20')
print(age1,age2) #20 20
# 按照二进制转换
age3 = int('10',base=2)
print(age3) # 2
我们可以定义一个int2()的函数,默认把base=2传进去:int2实际上就变成了部分参数(base)已经预置了的偏函数。
def int2(x, base=2):
return int(x, base)
print(int2('10')) # 2
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:
所以,functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。
三、总结
本文主要介绍了函数式编程及特点 和 python中内置的高阶函数及周边:
1.函数式编程的主要特点:允许有变量、函数可以作为变量、可以返回函数和支持匿名函数;
2.python中的内置函数:map()、reduce()、filter()、sorted()、闭包、匿名函数及偏函数等内容。
有问题欢迎大家评论区留言探讨,谢谢。
另附:python中http请求及网络爬虫获取数据:
1.Python 爬数据案例 客户端服务端http请求 推荐 【进阶篇 2 】-CSDN博客
2.python面向对象继承多态和一些特殊方法的使用
【python 入门篇 1 2 3 】
1.安装下载基本数据类型:Python 3 入门基础知识【1】数据类型 安装下载 推荐-CSDN博客
2.list数组定义及操作:Python 3 入门基础知识 之数据容器及用法【2】 推荐-CSDN博客