函数式编程
介绍:
当下主流的编程方法有三种:函数式,面向过程,面向对象,三者相当于编程界的三个门派,每个门派有自己的独门秘籍,都是用来解决问题的。三种流派都是一种编程的方法论,只不过是各自的风格不同,在不同的应用场景下也各有优势。
一:函数式编程:函数式=编程语言定义的函数+数学意义的函数
通俗来讲,函数式就是用编程语言去实现数学函数。这种函数内对象是永恒不变的,要么参数是函数,要么返回值是函数,没有for和while循环,所有的循环都由递归去实现,无变量的赋值(即不用变量去保存状态),无赋值即不改变。
y = 2*x+1 def cal(x): return 2*x+1
特征:
1.不可变数据
2.第一类对象
3.尾调用优化(尾递归)
例一:不可变:不用变量保存状态,不修改变量
#非函数式t a=1 def incr_test1(): global a a+=1 return a incr_test1() print(a) #函数式 n = 1 def incr_test2(n): return n+1 print incr_test2(2) print(n)
例二:第一类对象:函数即“变量”
1.函数名可以当参数传递
def foo(n): print(n) def bar(name): print('my name is %s' %name) foo(bar('丢丢'))
2.返回值可以是函数名
def bar(): print('from bar') def foo(): print('from foo') return bar n = foo() n()
例三:尾调用:在函数的最后一步调用另外一个函数(最后一行不一定是函数的最后一步)
#函数在bar内为尾调用 def bar(n): return n def foo(x): return bar(x) #函数在bar1和bar2在foo内均为尾调用,二者在if判断条件不同的情况下都有可能作为函数的最后一步 def bar1(n): return n def bar2(n): return n+1 def foo(x): if type(x) is str: return bar1(x) elif type(x) is int: return bar2(x) #函数bar在foo内为非尾调用 def bar(n): return n def foo(x): y=bar(x) return y #函数bar在foo内尾非尾调用 def bar(n): return n def foo(x): return bar(x)+1
高阶函数(满足下列条件之一即为高阶函数)
1.函数的传入参数是一个函数名
2.函数的返回值是一个函数名
map函数:依次处理列表每一个元素,得到结果是一个‘列表’,该‘列表’元素个数及位置与原来列表顺序一样
1 array=[1,3,4,71,2] 2 3 ret=[] 4 for i in array: 5 ret.append(i**2) 6 print(ret) 7 8 #如果我们有一万个列表,那么你只能把上面的逻辑定义成函数 9 def map_test(array): 10 ret=[] 11 for i in array: 12 ret.append(i**2) 13 return ret 14 15 print(map_test(array)) 16 17 #如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样 18 def add_num(x): 19 return x+1 20 def map_test(func,array): 21 ret=[] 22 for i in array: 23 ret.append(func(i)) 24 return ret 25 26 print(map_test(add_num,array)) 27 #可以使用匿名函数 28 print(map_test(lambda x:x-1,array)) 29 30 31 #上面就是map函数的功能,map得到的结果是可迭代对象 32 print(map(lambda x:x-1,range(5))) 33 34 35 #终极版本 36 37 num_l = [2, 5, 9, 8] 38 def map_test(func, array): 39 40 ret = [] 41 for i in num_l: 42 res = func(i) 43 ret.append(res) 44 return ret 45 46 47 print(map_test(lambda x:x+1,num_l))
filter函数:遍历序列中每个元素,判断每个元素布尔值,如果是True则留下来
people = [ {'name':'huanhuan','age':500}, {'name':'diudiu','age':500}, {'name':'haha','age':5}, ] print(list(filter(lambda p:p['age']<=18,people)))
#课堂上集聚了一群打游戏的同学,找出他们 class_people=['yunlai','lvzhi','lianhua','yx_longtao','yx_wukequn','yx_zhiying'] def tell_yx(x): return x.startswith('yx') def filter_test(func,array): ret=[] for i in array: if func(i): ret.append(i) return ret print(filter_test(tell_yx,class_people)) #函数filter,返回可迭代对象 print(filter(lambda x:x.startswith('yx'),class_people)) print(list(filter(lambda x:x.startswith('yx'),class_people)))
reduce函数:处理一个序列,然后把序列进行合并操作
# 求和 num_l=[2,5,6,9,14,56] res = 0 for num in num_l: res+=num print(res) # 函数形式 num_l=[1,6,9,15,100] def reduce_test(array): res=0 for num in num_l: res += num return res print(reduce_test(num_l)) # 乘积 num_l=[2,6,5] def reduce_test(func,array): res=1 #程序容易写死 for num in array: res=func(res,num) return res print(reduce_test(lambda x,y:x*y,num_l)) # 方法二: num_l = [2, 6, 5] def reduce_test(func, array): res = array.pop(0) for num in array: res = func(res, num) return res print(reduce_test(lambda x, y: x * y, num_l)) # 支持用户自己传入初始值 num_l = [2, 6, 9, 15] def reduce_test(func, array, init=None): if init is None: res = array.pop(0) else: res=init for num in array: res = func(res, num) return res print(reduce_test(lambda x, y: x * y, num_l, 100)) #reduce 函数 def reduce_test(func, array, init=None): if init is None: res = array.pop(0) else: res=init for num in array: res = func(res, num) return res from functools import reduce num_l = [2, 6, 9, 15] print(reduce(lambda x,y:x*y,num_l,100))
总结