函数式编程,使代码简洁高效。html
函数编程语言最重要的基础是λ演算(lambda calculus),函数能够像数值同样被赋值于变量,还能够做为其余函数的输入(引数)和输出(传出值)进行传递。python
函数能够当作参数来进行传递,造成所谓的高阶函数,形如 z=g(f(x),y)
,还能像变量同样被建立和修改。算法
Map函数:编程
map(func, *iterables),做用是将一个列表映射到另外一个列表。设计模式
class map(object): """ map(func, *iterables) --> map object Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted. """
使用方法:数组
def f(x): return x**2 li = range(1,10) res = map(f,li) print(res) print(list(res)) """ <map object at 0x000000000117E2E8> [1, 4, 9, 16, 25, 36, 49, 64, 81] """
map(function, iterable, ...)app
map()函数接收两个参数,一个是函数,一个是可迭代的对象,map将传入的函数依次做用到序列的每一个元素,返回一个map对象,不是list。编程语言
基本等价于 [f(x) for x in interable],列表推导比map效率要高一些ide
map(lambda x: x+1, range(1, 3)) => [x+1 for x in range(1,3)]函数式编程
str = ["far","foo","bar"] mp = map(lambda x:x.upper(),str) res = list(mp) print(res) """ ['FAR', 'FOO', 'BAR'] """
Reduce函数
reduce(function, sequence[, initial]),对可迭代对象依次作累计操做,如依次相加或相乘。
reduce()
方法接收一个函数做为累加器(accumulator),数组中的每一个值(从左到右)开始合并,最终为一个值。
def reduce(function, sequence, initial=None): # real signature unknown; restored from __doc__ """ reduce(function, sequence[, initial]) -> value Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty. """
直接使用会报错
reduce(lambda x, y : x + y, [1, 3, 5, 7, 9])
"""
NameError: name 'reduce' is not defined
"""
正确的使用是:reduce是functools中的一个函数,须要引用:from functools import reduce
使用方法:
from functools import reduce res1 = reduce(lambda x, y: x*y, [1, 2, 3]) res2 = reduce(lambda x, y : x + y, [1, 3, 5]) print(res1) print(res2) """ 6 9 """
Python内置的all()
,any()
,sum()
,max()
,min()
等函数都是从reduce()衍生而来。
Filter函数
filter(function or None, iterable),做用是按照所定义的函数过滤掉列表中的一些元素
class filter(object): """ filter(function or None, iterable) --> filter object Return an iterator yielding those items of iterable for which function(item) is true. If function is None, return the items that are true. """
使用方法:
flt = filter(lambda x: x > 5, range(10)) res = list(flt) print(flt) print(res) """ <filter object at 0x0000000000649A58> [6, 7, 8, 9] """
经过列表生成式,能够直接建立一个列表。但受内存限制,列表容量有限。建立一个包含100万个元素的列表,会占用很大的存储空间,若是咱们仅仅须要访问其中几个元素,那绝大多数元素占用的空间都白白浪费了。
因此,若是列表元素能够按照某种算法推算出来,那咱们是否能够在循环的过程当中不断推算出后续的元素呢?这样就没必要建立完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要建立一个generator,有不少种方法。最简单的方法是,只要把一个列表生成式的[]
改为()
,就建立了一个generator:
lis = [x*x for x in range(10)] # list gen = (x*x for x in range(10)) # generator对象,与list的区别,只是最外层的() print(lis) print(gen) """ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] <generator object <genexpr> at 0x000000000118C8E0> """
一个函数调用时返回一个迭代器,那这个函数就叫作生成器(generator);
若是函数中包含yield语法,那这个函数就会变成生成器。
def cube(n): for i in range(n): yield i ** 3 for i in cube(5): print(i) """ 0 1 8 27 64 """
生成器的特色:
1)生成器只有在调用时才会生成相应的数据;
2)只记录当前位置;
3)只有一个__next__()方法;
yield 的实现
def simple_yield(start): n = start while True: yield n n += 1 if __name__ == '__main__': for i in simple_yield(5): print(i) if i >= 10: break """ 5 6 7 8 9 10 """
从 simple_yield 中拿数据,拿到数据后,yield 会当即返回(可能有返回值),函数自己并无结束,只是被挂起,直到下次调用(for 循环会调用 next 方法)再从挂起的地方(yield)开始执行。
怎么打印出generator的每个元素?
一、若是要一个一个打印出来,能够经过next()
函数得到generator的下一个返回值;
二、for
循环迭代
lis = [x*x for x in range(10)] # list gen = (x*x for x in range(10)) # generator对象,与list的区别,只是最外层的() print(lis) print(gen) print(next(gen)) print(next(gen)) print(next(gen)) for i in gen: print(i) """ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] <generator object <genexpr> at 0x000000000119C8E0> 0 1 4 9 16 25 36 49 64 81 """
斐波拉契数列(Fibonacci)
除第一个和第二个数外,任意一个数均可由前两个数相加获得:1, 2, 3, 5, 8, 13, 21, 34, ...
def fib(max): n,a,b = 0,0,1 while n < max: print(b) a,b = b, a + b n += 1
能够直接做用于for
循环的数据类型有如下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些能够直接做用于for
循环的对象统称为可迭代对象:Iterable
。可使用isinstance()
判断一个对象是不是Iterable
对象。
from collections import Iterable lt1 = isinstance([],Iterable) lt2 = isinstance({},Iterable) lt3 = isinstance('abc',Iterable) lt4 = isinstance((x for x in range(10)), Iterable) lt5 = isinstance(100, Iterable) print(lt1, lt2,lt3,lt4,lt5) """ True True True True False """
凡是可做用于for
循环的对象都是Iterable
类型;
凡是可做用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable,
但不是Iterator
,不过能够经过iter()
函数得到一个Iterator
对象。
Python的for
循环本质上就是经过不断调用next()
函数实现的,例如:
for
x
in
[
1
,
2
,
3
,
4
,
5
]:
pass
# 首先得到Iterator对象: it = iter([1, 2, 3, 4, 5]) # 循环: while True: try: # 得到下一个值: x = next(it) except StopIteration: # 遇到StopIteration就退出循环 break
本质上是个函数,功能是装饰其余函数——就是为其余函数添加附加功能。
装饰器是一个很著名的设计模式,常常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,咱们就能够抽离出大量函数中与函数功能自己无关的雷同代码并继续重用。归纳的讲,装饰器的做用就是为已经存在的对象添加额外的功能。
装饰器原则:
1)不能修改被装饰函数的源代码;
2)不能修改被装饰函数的调用方式;
########## 基本装饰器 ########## def orter(func): #定义装饰器 def inner(): print("This is inner before.") s = func() #调用原传入参数函数执行 print("This is inner after.") return s #return原函数返回值 return inner #将inner函数return给name函数 @orter #调用装饰器(将函数name当参数传入orter装饰器) def name(): print("This is name.") return True #name原函数return True ret = name() print(ret) 输出结果: This is inner before. This is name. This is inner after. True
############ 装饰器传参数 ########### def orter(func): def inner(a,b): #接收传入的2个参数 print("This is inner before.") s = func(a,b) #接收传入的原函数2个参数 print("This is inner after.") return s return inner @orter def name(a,b): #接收传入的2个参数,并name总体函数当参数传入orter装饰器 print("This is name.%s,%s"%(a,b)) return True ret = name('nick','jenny') #传入2个参数 print(ret) 输出结果: This is inner before. This is name.nick,jenny This is inner after. True
########## 万能参数装饰器 ########## def orter(func): def inner(*args,**kwargs): #万能参数接收多个参数 print("This is inner before.") s = func(*args,**kwargs) #万能参数接收多个参数 print("This is inner after.") return s return inner @orter def name(a,b,c,k1='nick'): #接受传入的多个参数 print("This is name.%s,%s"%(a,b)) return True ret = name('nick','jenny','car') print(ret) 输出结果: This is inner before. This is name.nick,jenny This is inner after. True
########### 一个函数应用多个装饰器 ######### def orter(func): def inner(*args,**kwargs): print("This is inner one before.") print("This is inner one before angin.") s = func(*args,**kwargs) print("This is inner one after.") print("This is inner one after angin.") return s return inner def orter_2(func): def inner(*args,**kwargs): print("This is inner two before.") print("This is inner two before angin.") s = func(*args,**kwargs) print("This is inner two after.") print("This is inner two after angin.") return s return inner @orter #将如下函数总体当参数传入orter装饰器 @orter_2 #将如下函数当参数传入orter_2装饰器 def name(a,b,c,k1='nick'): print("This is name.%s and %s."%(a,b)) return True ret = name('nick','jenny','car') print(ret) 输出结果: This is inner one before. This is inner one before angin. This is inner two before. This is inner two before angin. This is name.nick and jenny. This is inner two after. This is inner two after angin. This is inner one after. This is inner one after angin. True
实现装饰器知识储备:
函数即“变量”
定义一个函数至关于把函数体赋值给了函数名
1.函数调用顺序
与其余高级语言相似,python不容许在函数未声明以前,对其进行引用或者调用
错误示范:
def foo(): print('in the foo') bar() foo() """ NameError: name 'bar' is not defined """
正确示范:(注意,python为解释执行,函数foo在调用前已经声明了bar和foo,因此bar和foo无顺序之分)
def foo(): print('in the foo') bar() def bar(): print('in the bar') foo() def bar(): print('in the bar') def foo(): print('in the foo') bar() foo() """ in the foo in the bar in the foo in the bar """
2.高阶函数
知足下列条件之一就可称函数为高阶函数
1.某一函数当作参数传入另外一个函数中
2.函数的返回值包含n个函数,n>0
高阶函数示范:
def bar(): print('in the bar') def foo(func): res=func() return res foo(bar) """ in the bar """
3.内嵌函数和变量做用域
在一个函数体内建立另外一个函数,这种函数就叫内嵌函数。
嵌套函数:
def foo(): def bar(): print('in the bar') bar() foo() """ in the bar """
局部做用域和全局作用域的访问顺序
x = 0 def grandpa(): def dad(): x = 2 def son(): x=3 print(x) son() dad() grandpa() """ 3 """
4.高阶函数+内嵌函数 ==》 装饰器
函数参数固定
def decorartor(func): def wrapper(n): print('starting') func(n) print('stopping') return wrapper def test(n): print('in the test arg is %s' %n) decorartor(test)('alex')
函数参数不固定
def decorartor(func): def wrapper(*args,**kwargs): print('starting') func(*args,**kwargs) print('stopping') return wrapper def test(n,x=1): print('in the test arg is %s' %n) decorartor(test)('alex',x=2222)
1.无参装饰器
import time def decorator(func): def wrapper(*args,**kwargs): start_time=time.time() func(*args,**kwargs) stop_time=time.time() print("%s" %(stop_time-start_time)) return wrapper @decorator def test(list_test): for i in list_test: time.sleep(0.1) print('-'*20,i) #decorator(test)(range(10)) test(range(10))
2.有参装饰器
import time def timer(timeout=0): def decorator(func): def wrapper(*args,**kwargs): start=time.time() func(*args,**kwargs) stop=time.time() print('run time is %s ' %(stop-start)) print(timeout) return wrapper return decorator @timer(2) def test(list_test): for i in list_test: time.sleep(0.1) print ('-'*20,i) #timer(timeout=10)(test)(range(10)) test(range(10))
3.终极装饰器
user,passwd = 'alex','abc123' def auth(auth_type): print('auth func:',auth_type) def outer_wrapper(func): def wrapper(*args,**kwargs): print("wrapper func args:",*args,**kwargs) if auth_type=="local": username = input("Username:").strip() password = input("Password:").strip() if user == username and passwd == password: res = func(*args,**kwargs) print("---after authentication") return res else: exit("\033[31;1mInvalid username or password\033[0m") elif auth_type == "ldap": print('搞毛线ldap,不会......') return wrapper return outer_wrapper def index(): print("welcome to index page") @auth(auth_type="local") #home = wrapper() def home(): print("welcome to home page") return "from home" @auth(auth_type="ldap") def bbs(): print("welcome to bbs page") index() print(home())#wrapper() bbs()
http://www.cnblogs.com/suoning/p/5499812.html