# -*- coding: utf-8 -*- """ Created on Thu Oct 10 18:31:33 2019 @author: Jason """ # ============================================================================= # 高阶函数Higher-order function # ============================================================================= # 函数本身也可以赋值给变量,即:变量可以指向函数 f=abs f(-10) #传入函数 def add (a,b,f): return f(a)+f(b) add(-5, 6, abs) # ============================================================================= # map() # ============================================================================= # map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。 def f(x): return x*x r=map(f,[1,2,3,4,5,6,7,8,9]) list(r) #等同: L=[] for n in [1,2,3,4,5,6,7,8,9]: L.append(f(n)) print(L) #转换为字符串 list(map(str,[1,2,3,4,5,6,7,8,9])) # ============================================================================= # reduce() # ============================================================================= #reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是: #reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) from functools import reduce def add(a,b): return a+b reduce(add,[1,3,5,7,9]) reduce(add,[add(1,3),5,7,9]) add(add(add(add(1,3),5),7),9) #把序列[1,3,5,7,9]变成13579 from functools import reduce def fn(x,y): return 10*x+y reduce(fn,[1,3,5,7,9]) def char2num(s): digits={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9} return digits[s] reduce(fn,map(char2num,'12345')) from functools import reduce DIGITS={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9} def str2num(s): def fn(x,y): return 10*x+y def char2num(s): return DIGITS[s] return reduce(fn,map(char2num,s)) # lambda()匿名函数 # lambda argument_list: expression # lambda 变量名: 表达式 from functools import reduce DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} def char2num(s): return DIGITS[s] def str2num(s): return reduce(lambda x,y : x*10+y,map(char2num,s) ) # ============================================================================= # 利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']: # ============================================================================= def normalize(name): return name.capitalize() def normalize(name): return name[0].upper()+name[1:].lower() L1 = ['adam', 'LISA', 'barT'] L2 = list(map(normalize, L1)) print(L2) from functools import reduce def prod(L): return reduce(lambda x,y : x*y , L) from functools import reduce def str2float(s): digits={'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'.':'.'} def char2num(a): return digits[a] def fn(x,y): if y=='.': return x else: return 10*x+y n=len(list(map(char2num,s)))-list(map(char2num,s)).index('.')-1 ans=(reduce(fn,map(char2num,s)))/(10**n) return ans print('str2float(\'123.456\') =', str2float('123.456')) if abs(str2float('123.456') - 123.456) < 0.00001: print('测试成功!') else: print('测试失败!') # ============================================================================= # filter() # ============================================================================= # filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。 # 在一个list中,删掉偶数,只保留奇数 def is_odd(n): return n%2==1 list(filter(is_odd,[1,2,3,4,5,6])) # 把一个序列中的空字符串删掉 def not_empty(s): return s and s.strip() list(filter(not_empty,['a','',None,'b','c','d'])) # 注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。 # ============================================================================= # 计算素数的埃氏筛法 # ============================================================================= def _odd_iter(): n = 1 while True: n=n+2 yield n def _not_divisiable(n): return lambda x:x%n!=0 def primes(): yield 2 it=_odd_iter() while True: n=next(it) yield n it = filter(_not_divisiable(n),it) for n in primes(): if n<1000: print(n) else: break # ============================================================================= # 练习:打印“回数” # ============================================================================= def is_palindrome(n): # ============================================================================= # sorted # ============================================================================= # sorted()函数可以对list排序 sorted([-21,-12,5,9,36]) # sorted(list,key=function) sorted([-21,-12,5,9,36],key=abs) # 字符串排序 # 由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面 sorted(['bob', 'about', 'Zoo', 'Credit']) # 忽略大小写排序 sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower) # 反向排序 sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower,reverse= True) # ============================================================================= # 返回函数 # ============================================================================= def calc_sum(*args): ax = 0 for n in args: ax=ax+n return ax def lazy_sum(*args): def sum(): ax=0 for n in args: ax=ax+n return ax return sum f=lazy_sum(1,3,5,7,9) f f() # ============================================================================= # 闭包(Closure) # ============================================================================= # 当我们调用lazy_sum()时,每次调用都会返回一个新的函数 f1=lazy_sum(1,3,5,7,9) f2=lazy_sum(1,3,5,7,9) f1==f2 def count(): fs=[] for i in range(1,4): def f(): return i*i fs.append(f) return fs f1,f2,f3=count() f1() f2() f3() def count(): def f(j): def g(): return j*j return g fs = [] for i in range(1, 4): fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f() return fs f1, f2, f3 = count() f1() f2() f3() # ============================================================================= # 匿名函数lambda # ============================================================================= f=lambda x: x * x def f(x): return x * x # ============================================================================= # 装饰器Decorator # ============================================================================= # 由于函数也是一个对象,而且函数对象可以被赋值给变量,变量能调用该函数 def now(): print('2019-10-12') f=now f() #函数对象有一个__name__属性 now.__name__ f.__name__ def log(func): def wrapper(*args,**kw): print('call %s():'%func.__name__) return func(*args,**kw) return wrapper #Python的@语法,把decorator置于函数的定义处 @log def now(): print('2019-10-12') now() #相当于now = log(now) #自定义log的文本: def log (text): def decorator (func): def wrapper(*args,**kw): print('%s %s():'%(text,func.__name__)) return func(*args,**kw) return wrapper return decorator @log('execute') def now(): print('2019-10-15') #和两层嵌套的decorator相比,3层嵌套的效果是这样的: now = log('execute')(now) #完整版本: import functools def log(func): @functools.wraps(func) def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper import functools def log(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator