您的位置:首页 > 编程语言 > Python开发

廖雪峰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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: