廖雪峰python学习笔记——函数式编程
2016-01-21 13:47
736 查看
廖雪峰python学习笔记——函数式编程
变量可以指向函数a=abs a(-2) #输出2
高级函数就是一个可以把一个函数当成参数的函数
def add(x,y,f): return f(x)+f(y) add(-3,-5,abs) #输出8
map函数
map()是Python内置的高阶函数,它接收一个f和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。reduce函数
reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。感觉这个函数比较难以理解,并且作用不大。reduce(函数名,链表[,第一个默认值])
filter函数
filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。#删除None和空字符串 def is_not_empty(s): return s and len(s.strip()) > 0 filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
str.strip()就是trim方法。
sorted排序
sorted函数可以对list进行排序sorted([26,5,12])
当然,sorted函数也可以接收一个比较函数来实现自定义排序。
def reversed_cmp(x,y): if x>y: return -1 if x<y: return 1 return 0 #或者使用下面这种写法 #return cmp(x, y) sorted([27,56,8], reversed_cmp)
***cmp比较大小:***cmp(s1.lower(), s2.lower())
返回函数
即返回值是一个函数。返回函数可以实现的一个功能就是,延迟执行。我们将该函数返回,当需要的时候再调用它。
def f(): print 'call f()...' # 定义函数g: def g(): print 'call g()...' # 返回函数g: return g
闭包
在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问。一个内层函数如果引用了外层函数的变量(即使是外层函数的变量当做内层函数的参数也算),并且返回内层函数的话,那么这种称为闭包。
如果内层函数引用了外层函数的变量,并且内层函数在运行之前,外层函数的变量发生的变化,那么这个内层函数的运行结果是有问题的。
如:
希望一次返回3个函数,分别计算1x1,2x2,3x3:
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(), f2(), f3()
实际返回的是3个9
修改上面实现:
它可以正确地返回一个闭包g,g所引用的变量j不是循环变量,因此将正常执行。
def count(): fs = [] for i in range(1, 4): def f(j): def g(): return j*j return g fs.append(f(i)) return fs f1, f2, f3 = count() print f1(), f2(), f3()
匿名函数
如:map(lambda x:x*x,[1,2,3,4,5,6]) #结果[1,4,9,16,25,36]
lambda表示匿名函数,:前面的x表示参数,后面表示表达式。
上面匿名函数等同于:
def f(x): return x*x
匿名函数的缺点:只能有一个表达式,不写return,返回值就是表达式。
装饰器
decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。编写无参数decorator
请编写一个@performance,它可以打印出函数调用的时间。import time def performance(f): def fn(*args, **kw): t1=time.time()#获取当前时间 r=f(*args, **kw) #*args, **kw确保了无论factorial有多少个参数都可以正常调用 t2=time.time() print 'call %s() in %fs' % (f.__name__, (t2 - t1)) # f.__name__返回函数的名字 return r return fn #这里返回了一个新的函数,这个新函数返回的是新添加的功能+原来的函数 @performance #@performance就相当于简写了factorial=performance(factorial) def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print factorial(10)
编写带参数decorator
其实就是在原来的performance函数的外面有嵌套了一层函数,新添加的函数接收参数。调用改变:@performance变为了@performance(args)
**import time def performance(unit): def performance1(f): def fn(*args, **kw): t1=time.time()#获取当前时间 r=f(*args, **kw) #*args, **kw确保了无论factorial有多少个参数都可以正常调用 t2=time.time() print '[%s]call %s() in %fs' % (unit, f.__name__, (t2 - t1)) # f.__name__返回函数的名字 return r return fn #这里返回了一个新的函数,这个新函数返回的是新添加的功能+原来的函数 return performance1 @performance('ms') #@performance就相当于简写了factorial=performance(factorial) def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print factorial(10)**
完善Decorator
# -*- coding:utf-8 -*- def f1(x): print 'call',x print f1.__name__#打印结果是f1 #有decorator的情况下,再打印函数名 def log(f): def wrapper(*args, **kw): print 'call...' return f(*args, **kw) return wrapper @log def f2(x): print 'call f2',x print f2.__name__#打印结果是wrapper #由于decorator返回的新函数函数名已经不是'f2',而是@log内部定义的'wrapper'。这对于那些依赖函数名的代码就会失效。
Python内置的functools可以把原来函数的必要属性一个一个复制到新函数上。
#3.functools复制函数信息 #有decorator的情况下,再打印函数名 def log3(f): @functools.wraps(f) #将f函数的所有属性信息拷贝到wrapper方法上 def wrapper(*args, **kw): print 'call...' return f(*args, **kw) return wrapper @log3 def f3(x): print 'call f3',x print f3.__name__#打印结果是wrapper
偏函数
有一个函数f1,需要很多个参数,使用比较麻烦。现在我们创建一个函数f2,f2调用f1,但是f2有一些参数是默认的。所以我们可以通过使用较少的参数调用f2来达到使用很多个参数调用f1相同的功能。functools.partial就是帮助我们实现这一个功能的。
# -*- coding:utf-8 -*- #偏函数 import functools int2 = functools.partial(int, base=2) print int2('10000'),int('10000',2) print int2('101001'),int('101001',2)
相关文章推荐
- 什么是尾递归(python引例)
- 【Python3】input/print:一行写不下,换多行
- 第一个kaggle项目Digit Recognizer
- Python模块常用的几种安装方式
- 【同行说技术】Python开发、调试、爬虫类工具大全
- python eval 函数妙用
- Python 入门之常见小问题
- Python函数
- 38. Count and Say leetcode python 2016 new season
- python 字典中的排序
- python中lambda的另类使用
- 升级python之后,yum下载东西时出现File "/usr/bin/yum", line 30
- Python面向对象学习
- Python之模块搜索路径
- 编写高质量代码--改善python程序的建议(六)续
- 编写高质量代码–改善python程序的建议(五)
- 编写高质量代码--改善python程序的建议(四)下
- 编写高质量代码--改善python程序的建议(四)上
- 编写高质量代码–改善python程序的建议(三)
- 编写高质量代码–改善python程序的建议(二)