Python函数式编程
Python版本:3.6.5
1、高阶函数
(1)、map/reduce:Python内建了map()和reduce()函数
1)、map: map接收2个参数,1个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
1]、例如:要打印出一个结果类似于 x^2 的list :我们可以先定义一个函数,然后把这个函数作为第一个参数传入map,第二个参数传这个函数的部分实参的集合list。
代码:
def x_sqrt(x):
return x*x
result = map(x_sqrt, [1,2,3,4,5])
print(list(result))
打印:
[1, 4, 9, 16, 25]
解释:map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是[惰性序列],因此通过list()函数让它把整个序列都计算出来并返回一个list。
扩展:把任意list数字转为字符串
代码:print(list(map(str,[2,3,565,878])))
打印:['2', '3', '565', '878']
2)、reduce:再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。
其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
1]、list求和:需要从functools中引入reduce方法
代码:
from functools import reduce
def add(x,y):
return x+y
result = reduce(add, [1,2,3,4])
print(result)
打印:
10
2]、要把序列 [1,2,3,4] 变成 1234 :
1.我们可以这样写:
代码:
from functools import reduce
def add(x,y):
return x*10+y
result = reduce(add, [1,2,3,4])
print(result)
2.还可以配合map把字符串 '1234'变成 1234
from functools import reduce
def add(x,y):
return x*10+y
def strToInt(str):
dicts = {'1':1,'2':2,'3':3,'4':4}
return dicts[str]
result = reduce(add, map(strToInt, '1234'))
print(result)
都打印:
1234
3)、filter: 和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数循环传入的于每个元素,然后保留为True结果,丢弃为False的结果。
1]、返回一个序列中为3的倍数的值
代码:
def threeN(x):
return x % 3 == 0
print(list(filter(threeN,[1,2,3,4,5,6,7,8,9])))
打印:
[3, 6, 9]
分析: filter()函数能够“筛选”出正确的值。并且filter()函数返回的也是一个Iterator惰性序列,需要用list()函数来返回结果集。
4)、排序算法:
1]、sorted()函数就可以对list进行排序
代码:print(sorted([3,-34,324,2]))
打印:[-34, 2, 3, 324]
2]、定义一个key参(函)数,按绝对值大小排序:key指定的函数会调用list的每一个元素,sorted根据key函数返回的结果进行排序。
代码:print(sorted([3,-34,324,2], key=abs))
打印:[2, 3, -34, 324]
3]、字符串排序
1.默认排序
代码:
nameArr = ['Zhangsan', 'liSi', 'wangWu', 'LiuLiu']
result = sorted(nameArr)
print(result)
打印:
['LiuLiu', 'Zhangsan', 'liSi', 'wangWu']
分析:
ASCII 中大写字母为65 小写字母为97,所以大写字母在小写字母之前。
2.忽略字母大小写排序:先把list全部转为大写 str.upper() 或小写 str.lower(),然后按从小到大排序
代码:
nameArr = ['Zhangsan', 'liSi', 'wangWu', 'LiuLiu']
result = sorted(nameArr, key=str.lower)
print(result)
打印:
['liSi', 'LiuLiu', 'wangWu', 'Zhangsan']
3.把结果按从大到小排列,按照方法2,再给函数加上第三个参数 reverse=True
代码:
nameArr = ['Zhangsan', 'liSi', 'wangWu', 'LiuLiu']
result = sorted(nameArr, key=str.lower, reverse=True)
print(result)
打印:
['Zhangsan', 'wangWu', 'LiuLiu', 'liSi']
2、返回函数
(1)、案例:返回一个计算累加和的函数
代码:
def cacl_total(*args):
def sum():
cnt = 0
for n in args:
cnt += n
return cnt
return sum
ret = cacl_total(1,2,3,4) #当我们调用cacl_total()时,返回的并不是求和结果,而是求和函数
print(ret) #调用函数 ret 时,才真正计算求和的结果
print(ret())
打印:
<function cacl_total.<locals>.sum at 0x04BB8150>
10
分析:
1]、我们 在函数 cacl_total 中又定义了 一个函数 sum ,sum内部函数可以获取函数 cacl_total 的参数和局部变量。
当我们调用 cacl_total 时,相关参数和变量都保存在返回的函数中。这就称为“闭包”程序。
2]、每次调用 cacl_total 返回的都是一个新的函数,即使传入相同的值,返回的函数还是不同的,互不影响。
(2)、闭包函数:注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用。
1)、返回的函数并没有立刻执行,而是直到调用了f()才执行
代码:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())
打印:
9
9
9
原因:原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
2)、 非要打印 1 4 9 :再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变
代码:
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())
3、匿名函数:关键字 lambda 冒号分开 加表达式 => lambda : x*x
(1)、代替之前的函数 x*x
代码:print(list(map(lambda x: x*x, [1,2,3,4])))
打印:[1, 4, 9, 16]
(2)、变量接收,变量调用
代码: f = lambda x: x*x
print(f(45))
打印:2025
(3)、把匿名函数作为返回值返回 lambda : x*y
代码:
def test(x,y):
return lambda : x*y
ret = test(3,7)
print(ret)
print(ret())
打印:
<function test.<locals>.<lambda> at 0x036C8150>
21
4、偏函数:通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点
(1)、 int() 函数把字符串转为整数,并提供额外的base参数,默认值是10,如果传base参数,就可以进行N进制的转换
print(int('1234',base=8))
print(int('1234',8))
输出:668 668
(2)、假设要转换许多二进制字符串,可以封装一个函数给默认值
def intTo2(x, base=2)
return int(x,base)
我们可以不定义 intTo2:
import functools
intTo2 = functools.partial(int,base=2)
print(intTo2('100000'))
Python函数式编程
最新推荐文章于 2024-09-13 17:59:44 发布