20191010

扫码查看
# -*- 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
01-13 02:36
查看更多