通过对一整段代码分成几个函数,相当于给每一个独立的程序逻辑取名字,使得代码变成自解释的。
准则 函数式编程的准则:不依赖于外部的数据,而且也不改变外部数据的值,而是返回一个新的值给你 。
1 2 3 4 int cnt;void increment(){ cnt++; }
1 2 3 int increment(int cnt){ return cnt+1 ; }
特性
不可变数据
first class functions
尾递归优化
技术 map & reduce
1 2 3 4 5 6 7 8 9 name_len = map (len , ["hao" , "chen" , "coolshell" ]) print name_lendef toUpper (item ):return item.upper()upper_name = map (toUpper, ["hao" , "chen" , "coolshell" ]) print upper_name
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 print reduce(lambda x, y: x+y, [1 , 2 , 3 , 4 , 5 ])num =[2 , -5 , 9 , 7 , -2 , 5 , 3 , 1 , 0 , -3 , 8 ] positive_num_cnt = 0 positive_num_sum = 0 for i in range (len (num)): if num[i] > 0 : positive_num_cnt += 1 positive_num_sum += num[i] if positive_num_cnt > 0 : average = positive_num_sum / positive_num_cnt print average
1 2 3 4 5 6 7 8 9 10 11 12 13 14 num =[2 , -5 , 9 , 7 , -2 , 5 , 3 , 1 , 0 , -3 , 8 ] positive_num_cnt = 0 positive_num_sum = 0 for i in range (len (num)): if num[i] > 0 : positive_num_cnt += 1 positive_num_sum += num[i] if positive_num_cnt > 0 : average = positive_num_sum / positive_num_cnt print average
1 2 positive_num = filter (lambda x: x>0 , num) average = reduce(lambda x,y: x+y, positive_num) / len ( positive_num )
pipeline
只关心输入和输出
recursing
1 2 3 4 5 6 7 8 9 10 def inc (x ): def incx (y ): return x+y return incx inc2 = inc(2 ) inc5 = inc(5 ) print inc2(5 ) print inc5(5 )
higher order function
消除共享变量和状态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from random import randomdef move_cars (): for i, _ in enumerate (car_positions): if random() > 0.3 : car_positions[i] += 1 def draw_car (car_position ): print '-' * car_position def run_step_of_race (): global time time -= 1 move_cars() def draw (): print '' for car_position in car_positions: draw_car(car_position) time = 5 car_positions = [1 , 1 , 1 ] while time: run_step_of_race() draw()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from random import randomdef move_cars (car_positions ): return map (lambda x: x + 1 if random() > 0.3 else x, car_positions) def output_car (car_position ): return '-' * car_position def run_step_of_race (state ): return {'time' : state['time' ] - 1 , 'car_positions' : move_cars(state['car_positions' ])} def draw (state ): print '' print '\n' .join(map (output_car, state['car_positions' ])) def race (state ): draw(state) if state['time' ]: race(run_step_of_race(state)) race({'time' : 5 , 'car_positions' : [1 , 1 , 1 ]})
pipeline 1)找出偶数。 2)乘以3 3)转成字符串返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 def process (num ): if num % 2 != 0 : return num = num * 3 num = 'The Number: %s' % num return num nums = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] for num in nums: print process(num)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def even_filter (nums ): for num in nums: if num % 2 == 0 : yield num def multiply_by_three (nums ): for num in nums: yield num * 3 def convert_to_string (nums ): for num in nums: yield 'The Number: %s' % num nums = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] pipeline = convert_to_string(multiply_by_three(even_filter(nums))) for num in pipeline: print num
使用map reduce而不使用循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def even_filter (nums ): return filter (lambda x: x%2 ==0 , nums) def multiply_by_three (nums ): return map (lambda x: x*3 , nums) def convert_to_string (nums ): return map (lambda x: 'The Number: %s' % x, nums) nums = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] pipeline = convert_to_string( multiply_by_three( even_filter(nums) ) ) for num in pipeline: print num
1 2 3 4 5 6 7 pipeline_func(nums, [even_filter, multiply_by_three, convert_to_string]) def pipeline_func (data, fns ): return reduce(lambda a, x: x(a), fns, data)
Shell风格函数写作方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Pipe (object ): def __init__ (self, func ): self.func = func def __ror__ (self, other ): def generator (): for obj in other: if obj is not None : yield self.func(obj) return generator() @Pipe def even_filter (num ): return num if num % 2 == 0 else None @Pipe def multiply_by_three (num ): return num*3 @Pipe def convert_to_string (num ): return 'The Number: %s' % num @Pipe def echo (item ): print item return item def force (sqs ): for item in sqs: pass nums = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] force(nums | even_filter | multiply_by_three | convert_to_string | echo)
原文:https://coolshell.cn/articles/10822.html