python函数式编程

作者: 小船翻不翻 | 来源:发表于2018-05-30 10:28 被阅读0次

    高阶函数

    把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
    与js相似,与c#中的委托一相似。

    • abs() 求一个数的绝对值
    #模拟abs得到一个数的绝对值
    def absFun(n):
        if n<0:
            return -n;
        return n
    
    • map(fn,list) 集合处理函数,作用到循环迭代对象的每个元素,返回新的对象
      fn是逐个处理元素的函数
    #将list值全部转换成字符串,str是一个函数(字符串转int使用int())
    >>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    #首字母大小,其他小写,处理map的示例
    def normalize(name):
        return name[0].upper()+name[1:].lower()
    #等同于
    lambda name:name[0].upper()+name[1:].lower()
    
    • reduce(fn,list) fn是函数需要两个参数,结果会累积,求和会用到
    reduce(lambda x,y:x*y,L)
    

    int()转换成整数,float()转换成浮点数,sum()求和,.index('.')符号.首次出现的下标,.upper()转换成大写,.lower()转换成小写

    def str2float(s):
        n=s.index('.')
        s=s[:n]+s[n+1:]
        DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
        def char2num(x):
            return DIGITS[x]
        return reduce(lambda x,y:10*x+y,map(char2num,s))/(10**(len(s)-n))
    
    • filter() 筛选过滤元素
      标准的写法:
    def not_empty(s):
        return s and s.strip()
    list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
    

    使用lambda便捷函数

    def _not_divisible(n):
        return lambda x : x%n > 0
    #等价于:
    def _not_divisible(n):
        def suibian(x):
            return x%n>0
        return suibian
    
    • sorted()排序算法
      对集合排序,忽略大小写,反向
    >>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
    ['Zoo', 'Credit', 'bob', 'about']
    

    用sorted()排序的关键在于实现一个映射函数。

    #对字典姓名,第三个字母进行排序
    L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
    def by_name(t):
        return t[0][2]
    

    闭包

    在一个函数内部定义另一个函数,它可以调用外部函数的参数和局部变量,就形成了闭包

    def count2():
        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
    #使用lambda简化
    def count3():
        fs = []
        for i in range(1, 4):
            def f(j):
                return lambda: j*j
            fs.append(f(i))
        return fs
    
    • 在count2中j的值被传入f()中,但不会执行g函数,而是返回了函数g
    • 函数count2返回的是一个集合,每个元素都是一个函数
      执行结果:
    >>> f1, f2, f3 = count2()
    >>> f1()
    1
    >>> f2()
    4
    

    使用闭包和生成器结合起来,形成每次调用就+1的效果:

    def createCounter():
        def dizeng ():
            a=1
            while True:
                yield a
                a =a+ 1
        def sd ():return next(g)#如果直接使用dizeng(),会导致多次执行该函数
        g = dizeng()#函数执行了一次,所以内部变量a只声明了一次,结果是一个生成器
        return sd#因调用方式,结果必须返回函数
    #调用函数
    counterA = createCounter()
    print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
    

    匿名函数

    使用lambda x: x * x这样方式的就是一个匿名函数
    x表示匿名函数的参数,:后面的是应用计算

    • 与普通函数应用方式一样,都可以作为变量或返回值
    • 因为没有名字,不必担心名称冲突的问题
    • 只能有一个表达式,返回值就是表达式的结果

    装饰器

    在函数的上面添加@函数名 的形式就是装饰器

    #定义了一个执行函数前,自动打印日志的功能函数
    def log(func):
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)
        return wrapper
    #定义一个应用函数
    @log
    def now():
        print('2015-3-25')
    
    • 执行now( )就相当于执行了log(now)( )
    • 除了@log标记,就是一个闭包函数的应用
    • 为了保持now函数的__name__属性不变,可以使用@functools.wraps(func)
    import functools
    def log(text):
        def decorator(func):
            @functools.wraps(func)#可保持得到的最终运行的函数__name__值仍是func的值
            def wrapper(*args, **kw):
                print('%s %s():' % (text, func.__name__))
                return func(*args, **kw)
            return wrapper
        return decorator
    #定义一个应用函数
    @log('execute')
    def now():
        print('2015-3-25')
    
    • 以上定义了一个带参数的log函数
    • 执行now( )就相当于执行了log('execute')(now)( )

    偏函数

    针对一些有默认值的函数,生成一个固定项的函数
    如int(x,base=10)参数base默认是10,如下:

    int2 = functools.partial(int, base=2)
    >>> int2('1000000')
    64
    

    生成了一个新的函数int2,调用int2(二进制字符串),得到十进制数字

    相关文章

      网友评论

        本文标题:python函数式编程

        本文链接:https://www.haomeiwen.com/subject/iryojftx.html