''' 函数式编程 高阶函数:满足两个特性任意一个即为高阶函数 1.函数的传入参数是一个函数名 2.函数的返回值是一个函数名 ''' ''' 面向过程:找到解决问题的入口,按照一个固定的流程去模拟解决问题的流程;违反开放封闭(OCP)原则,如果有一天需要加入一种Mothly类型,无疑需要修改这个方法; 这样的代码风格会让接下来的开发者不假思索的进行延续,比方说需要根据不同的活动类型延期活动;这样的代码风格违反了DRY原则,相同的而代码框架却无法重用。 函数式编程:函数式=编程语言定义的函数+数学意义的函数;通俗来讲,函数式就是用编程语言去实现数学函数。这种函数内对象是永恒不变的,要么参数是函数, 要么返回值是函数,没有for和while循环,所有的循环都由递归去实现,无变量的赋值(既不同变量去保存状态),无赋值即不改变。特征:不可变数据、第一类对象、 尾调用优化(尾递归) ''' #把函数当作参数传给另外一个函数 def foo(n): print(n) def bar(name): print('my name is %s' % name) foo(bar('alex')) #bar函数返回值为None,所以foo函数得到的实参值为None,打印的结果也就是None #返回值中包含函数 def bar1(): print('from bar1') def foo1(): print('from foo1') return bar1 print(foo1()()) def handle(): print('from handle') return handle h = handle() h() '''尾调用:在函数的最后一步调用另外一个函数(最后一行不一定是函数的最后一步);尾调用的关键在于是在函数的最后一步去调用别的函数,那么最后一步调用,有何好处? 根据函数即‘变量’的定义,定义a函数,a内调用函数b,b内调用函数c,在内存中会形成一个调用记录,又称调用帧(call frame),用于保存调用位置和内部变量等信息, 即a->b->c,直到c返回结果给b,c的调用记录才会消失,b返回给a,b的调用记录消失,a返回结果,a的调用记录消失,所有的调用记录,都是先进后出,形成了一个‘调用栈’(call stack)''' ''' map函数:传入一个方法和可迭代对象;内部使用循环将可迭代对象的每一个元素都使用一次方法,且将每一次得到的结果当成一个元素,生成一个迭代器。 ''' num_l = [1, 2, 10] #lambda x:x+1 def add_one(x): return x + 1 #lambda x:x-1 def reduce_one(x): return x - 1 #lambda x:x**2 def pf(x): return x ** 2 def map_test(func, array): ret = [] for i in array: res = func(i) ret.append(res) return ret n = map_test(add_one, num_l) print(n) m = map_test(lambda x:x+1, num_l) print(m) b = list(map(add_one, num_l)) print(b) v = list(map(lambda x:x+1, num_l)) print(v) msg = 'asd' print(list(map(lambda x:x.upper(), msg))) ''' filter函数:传入一个方法(返回值为bool值)和一个可迭代对象;内部使用循环对可迭代对象的每个元素使用一次方法,如果返回值为True,那么保存该元素,生成一个迭代器。 ''' movie_pople = ['sbalex', 'sbyuanhao', 'sbwupeiqi', 'mike'] #lambda name:name.startswith('sb) def sb_show(name): return name.startswith('sb') def filter_test(func, array): ret = [] for i in array: if not func(i): ret.append(i) return ret res = filter_test(sb_show, movie_pople) print(res) n = filter_test(lambda name:name.startswith('sb'), movie_pople) print(n) def sb_show1(name): return not(name.startswith('sb')) m = list(filter(sb_show1, movie_pople)) print(m) s = list(filter(lambda name:not name.startswith('sb'), movie_pople)) print(s) ''' reduce函数:传入一个方法和一个可迭代对象及一个默认参数,内部循环将可迭代对象自身元素按照所传入方法进行计算得出一个结果,当传入了默认参数,则默认参数作为初始值计算;需要导入functools模块中的reduce方法; ''' num = [2, 2, 3, 4, 5] # res = 1 # for i in num: # res *= i # print(res) #lambda x,y:x*y def abc(x, y): return x * y def test(func, num1, init=None): if init is None: res = num1.pop(0) else: res = init for i in num1: res = func(res, i) return res #print(test(abc, num)) print(test(lambda x,y:x*y, num, 2)) #两个print运行了两次test函数,test函数里的pop运行了两次,所以当两个print同时运行时,最后一个运行结果的列表少了一个元素 from functools import reduce #print(reduce(abc, num, 2)) print(reduce(lambda x,y:x*y, num, 2)) people = [ {'name':'alex', 'age':1000}, {'name':'mike', 'age':2000}, {'name':'jack', 'age':3000}, {'name':'mary', 'age':18}, ] print(list(filter(lambda x:x['age']<1000, people)))