• 廖雪峰--python教程:笔记四-函数式编程


    函数式编程:


    概念:是一种抽象程度很高的编程方式,允许将一个函数作为参数传入另一个函数,还允许返回一个函数。

    接下来介绍:

    map/reduce,filter,stored函数,返回函数,匿名函数,装饰器,偏函数

    map函数:

    问题:如果我想对一个列表[1,2,3,4,5,6,7,8,9]中的每一个元素求其平方:

    L = [1,2,3,4,5,6,7,8,9]
    
    def f(L):
        l = []
        for i in L:
            l.append(i*i)
        return l

    我们需要编写一个函数,然后作用在这个列表L上,有没有更简洁的写法呢?是有的,可以用map函数

    L = [1,2,3,4,5,6,7,8,9]
    def f(x):
        return x*x
    
    l = map(f,L)
    print(list(l))

    map()函数接收两个参数:第一个是函数名,第二个是Iterable,并将结果作为Iterator返回。(Iterable,Iterator的概念,请参考https://www.cnblogs.com/double-lin/p/9757953.html)

    reduce函数

    reduce是将函数f作用在序列[x1,x2,x3...]上,并且函数f接收两个参数:

    reduce(f,[x1,x2,x3,x4]) = f(f(f(x1,x2),x3),x4)

    from functools import reduce
    
    def fn(x,y):
        return 10*x +y
    
    reduce(fn,[1,2,3])

    练习一:利用map()函数,把用户输入的不规范的英文名字,变为首字母为大写,其他小写的规范名字。输入:['adam','LISA','barT'],输出:['Adam','Lisa','Bart']。

    #/usr/bin!
    '''
    首先,定义一个函数能够将字符串转变为,首字母大写其余小写;然后再将map函数作用在这个包含字符串的list集合上
    '''
    def toUpperLower(s):
        # 字符串长度
        m = len(s)
        first = s[0].upper()
        end = s[1:m].lower()
        return (first+end)
    
    print(list(map(toUpperLower,['adam','LISA','barT'])))

     练习二:Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:

    #/usr/bin!
    from funtools import reduce
    def prod(L):
        def fn(x,y):
            retrun(x*y)
        return reduce(fn,L)

    练习三:利用map()和reduce()编写一个str2float()函数,把字符串'123.456'转换为浮点型123.456

    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 strToFloat(s):
        s = s.split('.')
        if s[0]=='':
            first = 0.0
        else:
            first = reduce(lambda x,y: x*10 + y,map(char2num,s[0]))
        l = list(reversed(s[1]))
        l.append('0')
        end = reduce(lambda x,y: x*(1e-1) + y,map(char2num,l))
        return (first+end)
    
    print(strToFloat('.213'))

    filter函数

    python的内置函数filter函数和map函数类似,接收两个参数:函数和序列,和map()不同的是,filter()把函数以此作用在列表元素上,然后根据返回值是True还是False,来决定是否保留。

    练习四:回数是从左往右数和从右往左数都是一样的数,利用filter()函数,来筛选出来回数:

    def is_palindrome(num):
        s = str(num)
        if len(s)==1:
            return int(s)
        elif len(s)%2 == 0:
            for i in range(0,len(s)//2):
                if s[i] != s[len(s)-i-1]:
                    return
            return int(s)
        else:
            for j in range(0,len(s)//2):
                if s[j] != s[len(s)-j-1]:
                    return
            return int(s)
    
    output = filter(is_palindrome, range(1, 1000))
    print('1~1000:', list(output))
    
    if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
        print('测试成功!')
    else:
        print('测试失败!')

    sorted函数

    排序:sorted()也是一个高阶函数,可以用key=接收自定义的函数,和reverse=True或者False(默认False)逆序

    练习五:假设我们用一组tuple来表示学生的名字和成绩:L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)],请用sorted()函数对列表L分别按名字和成绩排序:

    L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
    def by_name(t):
        return t[0]
    
    def by_score(t):
        return t[1]
    
    sorted(L,key=by_name)
    sorted(L,key=by_score)

    匿名函数:

    通过使用lambda关键字,来定义一个简单的函数,lambda x: x*x

    冒号前的变量x是参数,返回结果x*x,冒号后,只能有一个表达式

    练习六: 请用匿名函数改造下列代码:

    def is_odd(n):
        return n % 2 == 1
    
    L = list(filter(is_odd,range(1,20)))
    
    #使用匿名函数
    L = list(filter(lambda n: n%2==1,range(1,20)))

    返回函数:

    函数作为结果值,返回。

    练习七:利用闭包返回一个计数器函数,每次调用它返回一个递增整数:

    参考:https://www.cnblogs.com/cccmon/p/7930550.html

    s = 0 #设置全局变量
    def createCounter():   
        def counter():
            global s #引用全局变量
            s = s+1
            return s
        return counter
    counterA = createCounter()
    print(counterA()) #每次调用子函数,都是会保留上次s的值进行计算的
    def createCounter():
        s = [0] 
        def counter():
            s[0] = s[0]+1
            return s[0]
        return counter

     装饰器:

    在动态执行函数的时候,我们希望在不改变原来函数代码的下,动态增强该函数的功能,如在调用的时候打印一下该函数的开始执行提示。

    练习八:写一个装饰器log,使其即满足:

    @log

    def f():

      pass

    又满足:

    @log('execute')

    def f():

      pass

    import functools
    
    
    def log(param):
        if callable(param):
            def wrapper(*args, **kw):
                print('%s function()' % (param.__name__))
                param(*args, **kw)
    
            return wrapper
    
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print('%s %s():' % (param, func.__name__))
                return func(*args, **kw)
    
            return wrapper
    
        return decorator

    偏函数:

    就是使调用函数的时候更简单一点:

     import functools
     int2 = functools.partial(int, base=2)
     int2('1000000')
    #输出: 64
  • 相关阅读:
    重置(reset) HANA的是system的密码
    Linux删除其他程序正在使用的文件
    ECC升级S/4HANA
    一步一步教你写SAP RFC
    如何查看MAXDB日志
    How to delete SAP* from HANA Tenant database(HANA数据库下如何删除SAP*账户)
    echo N>/proc/sys/vm/drop_caches清理缓存
    SUM in the family way
    vue 使用 autoprefixer amfeflexible postcsspxtorem 自动转rem移动端适配
    VueJS实现迷糊查询
  • 原文地址:https://www.cnblogs.com/double-lin/p/9831194.html
Copyright © 2020-2023  润新知