对于一个用命令式编程开发了好几年并且已经养成习惯的我来说,函数式编程瞬间深深的吸引了我,我之前从来都不曾想过或者不曾知道原来编程还可以这样做,思想大大的解放了。函数编程的核心的基础就是函数能够作为参数和返回参数,然后函数也能在函数里面定义,说白了函数就是一种对象,也许是js的思路一样,正因为上面这几点,直接导致了了函数式的各种各样的充满创意的写法,以下是写的一些例子和代码,网上很多的例子太简单,没有什么实用性,我这里是我看过经过思考来的。
# -*- coding: utf-8 -*- #1.lambda f=lambda x,y:x*y print f(1,2) #计算整个list的平方 a=range(10) print map(lambda x:x**2,a) #计算整个list的和,reduce print reduce(lambda x,y:x+y,a) #计算整个list的平方和 print reduce(lambda x,y:x+y,map(lambda x:x**2,a)) #选出一个list的一部分元素.filter,选出偶数 print filter(lambda x:x%2==0,a) # 等价写法: print [x for x in a if x%2==0] #选出索引为某些条件的enumerate a=[1,2,3,4,5,6] print 'chafen' print map(lambda(i,x):x-a[i-1] if i!=0 else a[0],enumerate(a)) #返回所有奇数的平方,选出奇数再map print map(lambda x:x**2,filter(lambda x:x%2==1,a)) def fun1(x): return True if x%2==1 else False #注意,这样写函数是变量,不能打括号! print map(lambda x:x**2,filter(fun1,a)) def fun2(x,y): return x+y print reduce(fun2,filter(fun1,a)) #双重循环 #1 aa=[1,2,3,4,5] bb=[3,2,4,5,6,8] print [ x*y for x in aa for y in bb if x*y>10] #2 取第一个列表和第二个列表相同的部分 print [x for x in aa for y in bb if x==y] print filter(lambda x:x in bb,aa) #3.取并集 差集 print 'bing ji' print list(set(aa).union(set(bb))) print list(set(bb).difference(set(aa))) # b中有而a中没有的 #print [ (x,y) for x in aa for y in bb if x!=y] #4.选出字符串最长的单词: st=['abc','dd','kkkk'] print reduce(lambda x,y:x if len(x)>len(y) else y,st) # a=[1,2,3,4,5,6] # reduce(lambda ,a,) import random names = ['Mary', 'Isla', 'Sam'] secret_names = map(lambda x: random.choice(['Mr. Pink', 'Mr. Orange', 'Mr. Blonde']), names) print 'sam' sentences = ['Mary read a story to Sam and Isla.', 'Isla cuddled Sam.', 'Sam chortled.'] sam_count = reduce(lambda a, x: a + x.count('Sam'), sentences, 0) print sam_count #闭包,求导数 ,接收一个函数,返回一个函数 #1. def d(f): def cal(x): dx=0.0000001 return (f(x+dx)-f(x))/dx return cal f=lambda x:x**2+1 #传外层的值和内层的值. print d(f)(2) f1=d(f) print f1(2) #求二阶导数 print d(d(f))(2) #2. def f(): #可读读取外面的值 n = 1 def inner(): print n return inner #test 闭包 f()() #偏函数 from functools import partial def mod(m,n): return m%n mod_by_100=partial(mod,100) print mod(100,7) print mod_by_100(7) #根据已经定义函数,动态设置默认值产生新的函数 print 'reduce other' #reduce 函数其他用法 第三个参数就是做累积初始值的, # 如果第三个参数没有指定的话,则把list的第一个元素当成初始值 c=[] def f(a): print a #reduce 必须要两个参数,所以用_代替,表示迭代的时候这个参数没用. print reduce(lambda _,x: f(x), range(3,10), 0) #柯里化(Currying)技术是把接受多个参数的函数变换成只接受部分参数(比如原函数的第一个参数) # 的函数,并且返回接受余下的参数的新函数,新函数称为偏函数。 def add(x, y): return x + y def add_to(n): return lambda x: add(n, x) assert add(3, 2) == add_to(3)(2) #根据平方和立方的关系定义. def power(x,a): return x**a def power_to(a): return lambda x:power(x,a) print power_to(2)(3) print power_to(3)(3) #类装饰器: import time def timeit(func): def wrapper(): start = time.clock() func() end =time.clock() print 'used:', end - start return wrapper @timeit def foo(): print 'in foo()' foo() #以上那句注解和下面这句是一样的 #timeit(foo)() # 一些之前说过的复习,下面等价 [x+1 for x in range(5)] map(lambda x:x+1, range(5)) [x for x in range(10) if x%2==0] filter(lambda x:x%2==0, range(10)) # for for k, v in {'a':1, 'b':2}.items(): pass for i, index in enumerate([1,2,3,4,5]): pass # 多重循环 ,惰性的用yielt实现的,也就是必须遍历才去拿值,本身是一个生成器 aaa=((x, y) for x in range(3) for y in range(x)) for mm in aaa: print mm # 组合循环,不是多重循环,并列而不是嵌套 #lst=[1,2,3,4,5] #(x.doSth() for x in (y.doSomething() for y in lst) if x>0) #生成器 def fibonacci(): a = b = 1 yield a yield b while True: a, b = b, a+b yield b for num in fibonacci(): if num > 100: break # ,表示同一行 print num,
import random def qsort1(L): if not L: return L pivot = L[0] def lt(x): return x<pivot def ge(x): return x>=pivot return qsort(filter(lt, L[1:]))+[pivot]+qsort(filter(ge, L[1:])) def qsort(L): if not L: return L pivot = random.choice(L) def lt(x): return x<pivot def gt(x): return x>pivot return qsort(filter(lt, L))+[pivot]*L.count(pivot)+qsort(filter(gt, L)) #cmp if same return 0 if < -1 if > 1 def q(x): def o(s): return [i for i in x if cmp(i,x[0])==s] return len(x)>1 and q(o(-1))+o(0)+q(o(1)) or x def q2(x): if len(x)>1: lt = [i for i in x if cmp(i,x[0]) == -1 ] eq = [i for i in x if cmp(i,x[0]) == 0 ] gt = [i for i in x if cmp(i,x[0]) == 1 ] return q(lt) + eq + q(gt) else: return x a=[2,3,4,5,1,6] print qsort(a) # fib cal from functools import wraps def memo(fn): cache = {} miss = object() @wraps(fn) def wrapper(*args, **kwargs): result = cache.get(args, miss) if result is miss: result = fn(*args) cache[args] = result return result return wrapper @memo def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2) # use Recursion def lsum(f, a, b): if (a>b): return 0 else: return f(a)+lsum(f, a+1, b) print lsum(lambda x:x, 1, 5) def tsum(f, a, b): def loop(a, acc): if a>b: return acc else: return loop(a+1, acc+f(a)) return loop(a,0) print tsum(lambda x:x, 1, 5)
# function programming map1=lambda x: x if x=='t'or x=='tf' else x[2:] with open('C:\\Users\\mycapital\\Desktop\\lost_commands.csv') as f: a=[line.split(',') for line in f.readlines()] with open('C:\\Users\\mycapital\\Desktop\\lost03.txt') as f: b=map(lambda x:x.split(' '),f.readlines()) # filter in b def filt(y): for x in a: if map1(x[2])==y[2] and x[3]==y[-5] and x[4]==y[5] and x[0]==y[-2]: return True else: return False # def repla(y): # for x in a: # if map1(x[2])==y[2] and x[3]==y[-5] and x[4]==y[5] and x[0]==y[-2]: # y[3],y[4]=x[5].replace('-',''),x[5].replace('-','') # return ' '.join(y) def wrapdo(y,x): y[3],y[4]=x[5].replace('-',''),x[5].replace('-','') return ' '.join(y) # wrap the repla def repla(y): return ' '.join([ wrapdo(y,x)for x in a if map1(x[2])==y[2] and x[3]==y[-5] and x[4]==y[5] and x[0]==y[-2] ]) #print repla(b[4]) c=map(repla,filter(filt,b)) with open('D:\\tttt.txt','a+') as f: f.write(''.join(c))