(1)函数式编程
- 函数:function
- 函数式:functional,一种编程范式
- 把计算视为函数而非指令
- Python不是纯函数式编程:允许有变量
- 支持高阶函数:函数也可以作为变量传入
- 支持闭包:有了闭包就能返回函数
(2)高阶函数
- 高阶函数的定义
- 变量可以指向函数
- 函数的参数可以接受变量
- 一个函数可以接受另一个函数作为参数
- 能够接受函数作为参数的函数就是高阶函数
- 变量指向函数名
# 将函数赋值给一个变量
>>> abs
<built-in function abs>
>>> a = abs
>>> a(-20)
20
# 将abs函数变成了长度函数
>>> abs = len
>>> abs(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>> abs([1,2,3])
3
#计算两个数的绝对值之和
def add(x,y,f):
return f(x)+f(y)
print add(-5,9,abs)
(3)内置高阶函数
- map(f,list):遍历
- 它接收一个函数f和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回
- map()函数不改变原有的 list,而是返回一个新的 list,需要用list转换一下
L = [1,2,3,4,5,6,7,8,9]
def aa(x):
return x*x
mmp = map(aa,L)
# <map object at 0x10de725c0>
print(mmp)
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
print(list(mmp))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(L)
- reduce():累加
- Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 functools 模块里,如果想要使用它,则需要通过引入 functools 模块来调用 reduce() 函数
- reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值
- reduce()还可以接收第3个可选参数,作为计算的初始值
from functools import reduce
L = [1,2,3,4]
def aa(x,y):
return x+y
# 20
print(reduce(aa,L,10))
print(L)
# 计算初始值和第一个元素:f(10, 1),结果为11
# 先计算头两个元素:f(11, 2),结果为13
# 再把结果和第3个元素计算:f(13, 3),结果为16
# 再把结果和第4个元素计算:f(16, 4),结果为20
- filter():过滤
- filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list,不改变原list
def is_not_empty(s):
return s and len(s.strip())>0
res = filter(is_not_empty,['test', None, '', 'str', ' ', 'END'])
# <filter object at 0x10c7c0748>
print(res)
# ['test', 'str', 'END']
print(list(res))
- sorted(iterable, key=None, reverse=False)
- iterable -- 可迭代对象。
- key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
- reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
L = [36, 5, 12, 9, 21]
# 默认升序 [5, 9, 12, 21, 36]
print(sorted(L))
# 指定key排序 [36, 21, 12, 9, 5]
print(sorted(L,key = lambda x:-x))
# 指定key排序 [5, 9, 12, 21, 36]
print(sorted(L,reverse=False))
# [36, 5, 12, 9, 21]
print(L)
(4)闭包-保存函数状态
- 闭包的特点
- 内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
- 闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变
def sum_stat(list):
def sum():
return len(list)
return sum
middle = sum_stat([1,2,3,4])
# <function sum_stat.<locals>.sum at 0x1019e28c8>
print(middle)
# 4
print(middle())
# 4
print(sum_stat([1,2,3,4])())
- 以下的例子发现f1 f2 f3的函数结果都是9,因为循环之后这三个函数的变量i已经变成了3
def count():
fs = []
for i in range(1,4):
def f():
return i*i
fs.append(f)
return fs
f1,f2,f3 = count()
# 9
print(f1())
# 9
print(f2())
# 9
print(f3())
# 避免引用循环变量,g所引用的变量j不是循环变量
def count1():
fs = []
for i in range(1,4):
def ff(j):
def gg():
return j*j
return gg
fs.append(ff(i))
return fs
g1,g2,g3 = count1()
# 1
print(g1())
# 4
print(g2())
# 9
print(g3())
(5)lambda匿名函数
- lambda其实就是一个匿名函数,只能有一个表达式,不写return,返回值就是该表达式的结果
- 冒号前面的 x 表示函数参数
aa = lambda x:x*x
print(aa(-3))
bb = lambda x:-x if x < 0 else x
print(bb(-3))
cc = lambda x,y:x*y
print(cc(3,4))
# 省略参数
aa = lambda:123
print(aa()) # 123
* 嵌套lambda
f = lambda x :lambda y:x+y
print(f(1)(2))
# 等效如下
def ff(x):
def aa(y):
x+y
return aa
print(ff(1)(2))
网友评论