• python基础之函数式编程


    一、函数的定义

    1、定义:函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

    2、特性:

    (1)减少重复代码;

    (2)使程序变的可扩展;

    (3)使程序变得易维护。

    3、函数的分类

    (1)内置函数:为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()

    (2)自定义函数:很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。

    例子:打印佛祖

     1 def print_buddha(): #def 函数名():定义函数名和变量名一样
     2     print("                            _ooOoo_   ")
     3     print("                           o8888888o  ")
     4     print("                           88  .  88  ")
     5     print("                           (| -_- |)  ")
     6     print("                            O\ = /O  ")
     7     print("                        ____/`---'\____  ")
     8     print("                      .   ' \| |// `.  ")
     9     print("                       / \||| : |||// \  ")
    10     print("                     / _||||| -:- |||||- \  ")
    11     print("                       | | \\\ - /// | |  ")
    12     print("                     | \_| ''\---/'' | |  ")
    13     print("                      \ .-\__ `-` ___/-. /  ")
    14     print("                   ___`. .' /--.--\ `. . __  ")
    15     print("                ."" '< `.___\_<|>_/___.' >'"".  ")
    16     print("               | | : `- \`.;`\ _ /`;.`/ - ` : | |  ")
    17     print("                 \ \ `-. \_ __\ /__ _/ .-` / /  ")
    18     print("         ======`-.____`-.___\_____/___.-`____.-'======  ")
    19     print("                            `=---='  ")
    20     print("  ")
    21     print("     .............................................  ")
    22     print("                  佛祖镇楼                BUG辟易  ")
    23     print("          佛曰:  ")
    24     print("                  写字楼里写字间,写字间里程序员;  ")
    25     print("                  程序人员写程序,又拿程序换酒钱。  ")
    26     print("                  酒醒只在网上坐,酒醉还来网下眠;  ")
    27     print("                  酒醉酒醒日复日,网上网下年复年。  ")
    28     print("                  但愿老死电脑间,不愿鞠躬老板前;  ")
    29     print("                  奔驰宝马贵者趣,公交自行程序员。  ")
    30     print("                  别人笑我忒疯癫,我笑自己命太贱;  ")
    31     print("                  不见满街漂亮妹,哪个归得程序员?")
    32 print_buddha()  #执行函数,加()就是执行,不加()打印的是函数的内存地址

    二、函数的定义和调用

    1、定义函数

    格式:

    #语法def 函数名(参数1,参数2,参数3,...):
        '''注释'''
        函数体
        return 返回的值
    
    

    注意:函数名要能反映其意义

    demo:

    def print_name():  #定义函数
        print('-----------------------------')  #代码块
        print('my name is renyz.')
        print('-----------------------------')
    print_name()  #调用函数

    注意:函数在定义阶段只检测语法,不执行代码

    也就是说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行时才会知道。

    2、调用函数

      定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它调用函数很简单的,通过 函数名() 即可完成调用

      函数的调用:先找到名字,根据名字调用代码(函数名加括号)

    3、分析函数的执行过程

    (1)回顾程序执行的三种流程

    顺序执行、选择执行、循环执行

    (2)函数的执行过程

    # 定义函数
    def print_info():     # 1、程序从第一行开始执行,发现定义一个函数print_info
        # 函数功能代码
        print ("-"*50)  # 3、开始依次执行代码
        print("名片管理系统...")
        print ("人生苦短,我用python")
        print(" 1:登录")
        print(" 2:退出")
        print ("-" * 50)  # 4、执行到这一步,从哪里进去的从哪里出去
    # 调用函数
    print_info() # 2、加括号代表执行   # 最后函数print_info走到这里 开始调用里面的函数。

    4、定义多个函数

    5、定义函数的三种形式

    (1)无参:应用场景仅仅只是执行一些操作,比如与用户交互、打印

    1 def auth():
    2     name = input(">>>:").strip()
    3     password = input("passwd>>>:").strip()
    4     if name == "test" and  password == "123":
    5         print("login successfull")
    6     else:
    7         print("user or password error")
    8 auth()

    (2)有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值

    1 def my_max(x,y):
    2     if x > y:
    3         print(x)
    4     else:
    5         print(y)
    6 my_max(1,3)

    (3)空函数:设计代码结构

    1 def placeholder():
    2     pass

      pass,什么也不做,占位用

    结论:

    (1)定义时无参,意味着调用时也无需传入参数

    (2)定义时有参,意味着调用时则必须传入参数

    三、函数的参数与局部变量

    1、形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量(在定义阶段函数名称括号内的参数叫做形参,可以给默认值)

    2、实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值(在执行阶段传入的参数叫做实参,可以是位置参数,也可以以键值对的形式传参,还可以传入函数的执行结果)

    def sum(x,y):    #x,y为形参
         print(x)
         print(y)
    sum(10,20)    #10,20代表实参

    3、默认参数(缺省参数)

    def stu_register(name, age, country, course):
        print("注册学生信息".center(25,'-'))
        print("姓名:", name)
        print("age:", age)
        print("国籍:", country)
        print("课程:", course)
    
    stu_register("王小二", 22, "CN", "python_devops")
    stu_register("张吃货", 21, "CN", "linux")
    stu_register("刘老根", 25, "CN", "linux")

      发现 country 这个参数 基本都 是"CN", 就像我们在网站上注册用户,像国籍这种信息,你不填写,默认就会是 中国, 这就是通过默认参数实现的,把country变成默认参数非常简单

    def stu_register(name, age, course, country='CN'):

      这样,这个参数在调用时不指定,那默认就是CN,指定了的话,就用你指定的值。

    4、关键参数

      正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。

    5、非固定参数(不定长)(*args-元组;**kwargs-字典)

    若函数在定义时不确定想传入多少个参数,就可以使用非固定参数

    def stu_register(name, age, *args):  # *args 会把多传入的参数变成一个元组形式
        print(name, age, args)
    stu_register("Renyz", 22)
    # 输出
    # Renyz 22 () #后面这个()就是args,只是因为没传值,所以为空
    stu_register("Jack", 32, "CN", "Python")
    # 输出
    # Jack 32 ('CN', 'Python')

    还可以有一个**kwargs(key=values)

    1 def stu_register(name, age, *args, **kwargs):  # *kwargs 会把多传入的参数变成一个dict形式
    2     print(name, age, args, kwargs)
    3 stu_register("Renyz", 18)
    4 # 输出
    5 # Renyz 18 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空
    6 stu_register("Jack", 22, "CN", "Python", sex="Male", province="ShanDong")
    7 # 输出
    8 # Jack 22 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}

    6、全局与局部变量

    在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
    全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
    当全局变量与局部变量同名时:
    在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
     1 name = "Renyz"
     2 def change_name(name):
     3     print("Old name:", name)
     4     name = "任彦忠"
     5     print("Change name:", name)
     6 change_name(name)
     7 print("在外面看看变量name改了么?", name)
     8 -----------------------------------------------------------
     9 Old name: Renyz
    10 Change name: 任彦忠
    11 在外面看看变量name改了么? Renyz
    #内置名称空间:(python启动时就有)python解释器内置的名字,print,max,min
    #全局名称空间:(执行python文件时启动)定投定义的变量
    #局部名称空间:(调用函数时启动,调用结束失效)函数内部定义的变量
    # 总结:三者的加载顺序
    # 内置 --->全局 - -->局部
    # 三者的访问顺序
    # 局部 --->全局 - -->内置

    四、返回值

    要想获取函数的执行结果,就可以用return语句把结果返回

    注意:

    1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
    2. 如果未在函数中指定return,那这个函数的返回值为None 
     1 def test():
     2     a = 11
     3     b = 12
     4     c = 33
     5     # return a
     6     # return b
     7     # return c  #无法调用多个值
     8 #调用多个值得方法:
     9     # 第1种 ,用一个列表来封装3个变量的值
    10     # d = [a,b,c]
    11     # return d
    12     # 第2种,第一种的另外写法
    13     # return [a,b,c]
    14     # 第3种 封装到元祖里面返回
    15     return a,b,c
    16 num = test()
    17 print (num)
    18 # return隐藏的功能结束函数的执行
    无return->None;return 1个值->返回1个值;return 逗号分隔多个值->元组
    什么时候该有返回值?
       调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
       通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
    什么时候不需要有返回值?
       调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
       通常无参函数不需要有返回值

    注意:每次调用一次函数的时候都会从函数最开始的地方执行。想做到用生成器(yiled)

    4种函数的类型:

      无参数,无返回值;无参数,有返回值;有参数,无返回值;有参数,有返回值

    def 函数名():
        pass
    
    def 函数名():
        return xxx
    
    def 函数名(参数):
        pass
    
    def 函数名(参数):
        return xxx

    五、嵌套函数

    1、 函数可以嵌套调用:

    def test1():
        pass
    def test2():
        print ('-------2-1------')
        print ('-------2-2------')
    def test3():
        print ("--------3-1-----")
        test2()  #在test3函数中调用test2函数
        print ("--------3-2-----")
    test3()

      如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置。

    例子:

     1 # 定义一个函数,这个函数接受三个参数,从键盘把这三个参数传递给函数, 让这个函数把这三个值的结果打印出来。
     2 def sun_3_nums(a,b,c):
     3     result = a+b+c
     4     print ("%d+%d+%d=%d"%(a,b,c,result))
     5 # 获取三个数值
     6 num1 = int(input("第一个值:"))
     7 num2 = int(input("第二个值:"))
     8 num3 = int(input("第三个值:"))
     9 sun_3_nums(num1,num2,num3 )
    10 -----------------------------------------------------------------------
    11 第一个值:3
    12 第二个值:4
    13 第三个值:5
    14 3+4+5=12
     1 # 改需求;完成三个值的平均值的计算:
     2 def sun_3_nums(a,b,c):#形参
     3     result = a+b+c
     4     # print ("%d+%d+%d=%d"%(a,b,c,result))
     5     return result
     6 def average_3_nums(a1,a2,a3):#  表示接收传的3个值  ; 形参  # 和外层的 abc没有关系
     7     result = sun_3_nums(a1,a2,a3) # a1,a2,a3保持三个值 ;实参
     8     result = result/3
     9     print ('平均值是:%d'%result)
    10 # 获取三个数值
    11 num1 = int(input("第一个值:"))
    12 num2 = int(input("第二个值:"))
    13 num3 = int(input("第三个值:"))
    14 # sun_3_nums(num1,num2,num3 )
    15 average_3_nums(num1,num2,num3 )# 表示被调用给函数传的值;实参
    16 #形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定

    2、嵌套函数

    name = 'Renyz'
    def change_name1():
        name = 'Yan12'
        def change_name2():
            name = 'Zhong12'
            print("第三层的名字:%s"%name)
        change_name2()  #调用内层函数
        print("第二层的名字:%s" % name)
    change_name1()
    print("最外层的名字:%s"%name)

    六、递归函数

      在函数内部,可以调用其他函数。如果一个函数在内部调用自己本身,这个函数就是递归函数。

     例子1:计算阶乘n!=1x2x3x...xn

    def factorial(n):
        if n == 1:
            return 1
        return n * factorial(n-1)
    fact = factorial(5)
    print(fact)
    --------------------------------------------
    120

     例子2:

    def calc(n):
        print(n)
        if int(n / 2) == 0:
            return n
        return calc(int(n / 2))
    calc(10)
    ---------------------------------------------
    10
    5
    2
    1

    递归特性:

    (1)必须有一个明确的结束条件

    (2)每次进入更深一层递归时,问题规模相比上次递归都应有所减少

    (3)递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

    应用案例3:(二分查找)

    data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
    def binary_search(dataset, find_num):
        print(dataset)
        if len(dataset) > 1:
            mid = int(len(dataset) / 2)
            if dataset[mid] == find_num:  # find it
                print("找到数字", dataset[mid])
            elif dataset[mid] > find_num:  # 找的数在middle左面
                print("33[31;1m找的数在middle[%s]左面33[0m" % dataset[mid])
                return binary_search(dataset[0:mid], find_num)
            else:  # 找的数在middle右面
                print("33[32;1m找的数在middle[%s]右面33[0m" % dataset[mid])
                return binary_search(dataset[mid + 1:], find_num)
        else:
            if dataset[0] == find_num:  # find it
                print("找到数字啦", dataset[0])
            else:
                print("没的分了,要找的数字[%s]不在列表里" % find_num)
    binary_search(data, 23)

    七、匿名函数(lambda)

     匿名函数就是不需要显式的指定函数

    def test(x,y):
        c = x*y
        print(c)
    test(2,5)
    #换成匿名函数
    # res = lambda x,y: x*y
    # print(res(2,5))
    print((lambda x,y: x*y)(2,5))

    匿名函数主要是和其他函数搭配使用

    res = map(lambda x:x**2,[1,5,7,4,8])
    for i in res:
        print(i)
    print(list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])))

    有名字的函数与匿名函数的对比:

    (1)有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能

    (2)匿名函数:一次性使用,随时随地定义

    #lambda的使用场景:  #max sorted map filter
    info = {
        'li':2000,
        'zhao':35000,
        'wu': 34000,
        'du': 40000
    }
    # max
    # def func(k):
    #     return info[k]
    # print(max(info,key=lambda k:info[k]))
    
    # sorted
    # print(sorted(info,key=lambda k:info[k],reverse=True))
    
    # zip,拉链
    # l1 = [1,2,3,4]
    # l2 = ['a','b','c']
    # print(list(zip(l1,l2)))
    
    # map,映射
    # names = ['zhao','wu','du']
    # l1 = []
    # for name in names:
    #     res = '%s_SB' % name
    #     l1.append(res)
    # print(l1)
    # print(list(map(lambda name:'%s_sb' % name,names)))
    
    # filter,过滤
    # names = ['zhao_sb', 'wu_sb', 'du_sb','li']
    # print(list(filter(lambda i: not i.endswith('_sb'),names)))

    八、函数式编程

      函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

      函数式编程中的函数这个术语不是指计算机中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其他状态。比如sqrt(x)函数计算x的平方根,只要x不变,不论什么时候调用,调用几次,值都是不变的。

      Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

      简单说,"函数式编程"是一种“编程范式”(programming paradigm),也就是如何编写程序的方法论。主要思想是把运算过程尽量写成一系列嵌套的函数调用。

    九、高阶函数

      变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接受另一个函数作为参数,这种函数九称之为高阶函数。

    def add(x,y,f):
        return f(x) + f(y)
    result = add(2,4,abs)
    print(result)

    1、map/reduce

    map()[映射]函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

    例子:有一个函数f(x)=x**2,要把这个函数作用在一个list[1,2,3,4,5,6,7,8,9]上

    def f(x):
        return x*x
    r = map(f,[1,2,3,4,5,6,7,8,9])
    print(r)
    print(list(r))
    ----------------------------------------
    <map object at 0x00000085DC852320>
    [1, 4, 9, 16, 25, 36, 49, 64, 81]

    map()作为高阶函数,它把运算规则抽象了,它还可以计算任意复杂的函数,比如,把list所有数字转为字符串;

    print(list(map(str,[1,2,3,4,5,6,7,8,9])))
    --------------------------------------------------
    ['1', '2', '3', '4', '5', '6', '7', '8', '9']

    map()还可以结合lambda匿名函数使用:

    names = ['ren','bi','li']
    l1 = []
    for name in names:
        res = '%s_NB'%name
        l1.append(res)
    print(l1)
    print(list(map(lambda name:'%s_nb'% name,names)))
    ------------------------------------------------------------------
    ['ren_NB', 'bi_NB', 'li_NB']
    ['ren_nb', 'bi_nb', 'li_nb']

    reduce是把一个函数作用在一个序列[x1,x2,x3,...]上,这个函数必须接受两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

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

    例如:一个序列求和,就可以用reduce实现:

    from functools import reduce
    def add(x,y):
        return x + y
    print(reduce(add,[1,2,3,4,5]))
    ------------------------------------------
    15

    在python中求和可以用sum()函数,但如果把序列[1,2,3,4,5]变换成整数12345,就可以用到reduce了:

    rom functools import reduce
    def add(x,y):
        return x * 10 + y
    print(reduce(add,[1,2,3,4,5]))
    ------------------------------------------
    12345

    如果考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),就可以写出把str转换为int的函数:

    from functools import reduce
    def add(x,y):
        return x * 10 + y
    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(add, map(char2num, '12345'))
    --------------------------------------------------------------
    12345

    整理成一个str_to_int的函数就是:

    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 str_to_int(s):
        def add(x,y):
            return x * 10 + y
        def char(s):
            return DIGITS[s]
        return reduce(add,map(char,s))
    print(str_to_int('123'))
    -----------------------------------------------------------------------
    123

    还可以用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 char2int(s):
        return reduce(lambda x,y:x*10+y,map(char2num,s))
    print(char2int('345'))
    -------------------------------------------------------------------------
    345

    也就是说,假如python没有提供int()函数,也可以写一个字符串转化为整数的函数。

    2、filter

     filter()也接收一个函数和一个序列,它把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

    例子1:在一个list中,删掉偶数,只保留奇数:

    def is_odd(n):
        return n % 2 == 1
    print(list(filter(is_odd,[1,2,3,4,5,6,7,8])))
    --------------------------------------------------------------
    [1, 3, 5, 7]

    例子2:把一个序列中的空字符串删掉:

    def not_empty(s):
        return s and s.strip()
    print(list(filter(not_empty,['a','b',None,'d',' ',])))
    -------------------------------------------------------------
    ['a', 'b', 'd']

    filter()这个高阶函数,关键在于正确实现一个“筛选”函数;并且它返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。

    例子3:用filter求素数

      计算素数的一个方法时埃氏筛法,它的算法可以理解为:

      首先,列出从2开始的所有自己数,构造一个序列:

      2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

      取序列的第一个数2,它一定是素数,然后用2把序列的2的倍数筛掉:

      3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

      取新序列的第一个数3,它一定是素数,然后用3把序列的3的倍数筛掉:

      5, 6, 7, 8910, 11, 12, 13, 141516, 17, 18, 19, 20, ...

      取新序列的第一个数5,然后用5把序列的5的倍数筛掉:

      7, 8910, 11, 12, 13, 141516, 17, 18, 19, 20, ...

      不断筛下去,就可以得到所有的素数。

      用Python来实现这个算法,可以先构造一个从3开始的奇数序列:

    def _odd_iter():
        n = 1
        while True:
            n = n + 2
            yield n    #注意:这是一个生成器,并且是一个无限序列

      然后定义一个筛选函数:

    def _not_divisible(n):
        return lambda x : x % n > 0

      最后,定义一个生成器,不断返回下一个素数:

    def primes():
        yield 2
        it = _odd_iter()
        while True:
            n = next(it)
            yield n
            it = filter(_not_divisible(n),it)

      这个生成器先返回第一个素数2,然后,利用filter()不断产生筛选后的新的序列。

      由于primes()也是一个无限序列,所以调用时需要设置一个退出循环的条件:

    for n in primes():
        if n < 1000:
            print(n)
        else:
            break

      注意到Iterator是惰性计算的序列,所以我们可以用python表示“全体自然数”,“全体素数”这样的序列,二代吗非常简洁。

    例子4:filter(过滤)搭配lambda函数使用

    names = ['zhao_sb', 'wu_sb', 'du_sb','li']
    print(list(filter(lambda i: not i.endswith('_sb'),names)))
    ----------------------------------------------------------------
    ['li']

    3、sorted

    排序算法

    排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。

    Python内置的sorted()函数就可以对list进行排序:

    l1 = [1,3,5,-2,-6,2]
    print(sorted(l1))
    ------------------------------------
    [-6, -2, 1, 2, 3, 5]

    此外,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

    l1 = [1,3,5,-2,-6,2]
    print(sorted(l1,key=abs))
    --------------------------------------------------------
    [1, -2, 2, 3, 5, -6]

    key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。对比原始的list和经过key=abs处理过的list;

    字符串排序的例子:

    s1 = ['a','d','A','z','B']
    print(sorted(s1))
    --------------------------------------------------
    ['A', 'B', 'a', 'd', 'z']

    默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'A' < 'a',结果,大写字母A会排在小写字母a的前面。

    现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能用一个key函数把字符串映射为忽略大小写排序即可。忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。

    这样,我们给sorted传入key函数,即可实现忽略大小写的排序:

    s1 = ['a','d','A','z','B']
    print(sorted(s1,key=str.lower))
    --------------------------------------------
    ['a', 'A', 'B', 'd', 'z']

    要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True

    s1 = ['a','d','A','z','B']
    print(sorted(s1,key=str.lower,reverse=True))
    ----------------------------------------------------------
    ['z', 'd', 'B', 'a', 'A']

    结合lambda函数使用:

    info = {
        'li':2000,
        'zhao':35000,
        'wu': 34000,
        'du': 40000
    }
    print(sorted(info,key=lambda k:info[k],reverse=True))
    --------------------------------------------------------------------
    ['du', 'zhao', 'wu', 'li']

    4、zip

    #zip,拉链
    l1 = [1,2,3,4]
    l2 = ['a','b','c']
    print(list(zip(l1,l2)))
    ----------------------------------------------------
    [(1, 'a'), (2, 'b'), (3, 'c')]

    5、max

    info = {
        'li':2000,
        'zhao':35000,
        'wu': 34000,
        'du': 40000
    }
    # def func(k):
    #     return info[k]
    # print(max(info,key=func))
    print(max(info,key=lambda k:info[k]))  #等于前面三行的内容
    info2 = [2,3,412,5,23,1,53,123]
    print(max(info2)

    详细讲解:https://www.liaoxuefeng.com/wiki/1016959663602400/1017328655674400

    十、内置函数

     详情参考:https://docs.python.org/3/library/functions.html?highlight=built#ascii

    1、abs() #函数返回数字的绝对值。
        a = 3
        b = -5
        print(abs(a))  #输出3
        print(abs(b))  #输出5
    2、eval() #将字符串str当成有效的表达式来求值并返回计算结果
        s = "1+2*3"
        print(type(s))
        print(eval(s))
    3、float()  #将一个字符串或整数转换为浮点数
        print(float())
        print(float('123'))
        print(float('1'))
    4、len()  #返回对象长度
    5、help()  #返回对象的帮助文档
        print(help())
    6、id()  #返回对象的内存地址
    7、input()  #获取用户输入内容
    8、range()  #根据需要生成一个指定范围的数字,可以提供你需要的控制来迭代指定的次数
        #用于创建包含连续算术值的列表(list)。
        #常用于for循环。参数必须是普通整数。
        for i in range(0,3):
            print(i)
        #第一个参数是起始数,第二个是终止数(不包含这个),第三个数步数
        for i in range(0,10,2):
            print(i)
    匿名函数:
        my_func = lambda a, b, c: a * b
        print(my_func)
        print(my_func(1, 2, 3))
        #结合map
        print('lambda结合map')
        l1 = [1, 3, 5, 7, 9]
        l2 = [2, 4, 6, 8, 10]
        result = map(lambda x, y: x * 2 + y, l1, l2)
        print(list(result))
    9、list函数() #方法用于将元组转换为列表。
        atuple = ('q','w','e','r')
        l1 = list(atuple)
        print(l1)             #输出['q', 'w', 'e', 'r']
    10、元组 tuple() #函数将列表转换为元组。
        l1 = [1,2,3,4,5]
        t1 =tuple(l1)
        print(t1)       #输出(1, 2, 3, 4, 5)
    11、type函数()    #返回对象类型
    12、hash() #用于获取取一个对象(字符串或者数值等)的哈希值
        hash 语法:
        hash(object)
        print(hash('set')) # # 字符串
        print(hash(133))  # 数字
        print( hash(str([1,2,3]))) ## 集合
        print(hash(str(sorted({'1':1}))))#  字典
    13、zip() #函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。
        如果各个可迭代对象的元素个数不一致,则返回的对象长度与最短的可迭代对象相同。
        利用 * 号操作符,与zip相反,进行解压。
        v1 = [1, 2]
        v2 = [3, 4]
        v3 = [5, 6]
        v = zip(v1, v2, v3)  # 压缩
        print(list(v))
        w = zip(*zip(v1, v2, v3))  # 解压
        print(list(w))
    搭配for循环支持并行迭代:
        list1 = [2, 3, 4]
        list2 = [4, 5, 6]
        for x, y in zip(list1, list2):
            print(x, y, '--', x * y)
        # 例如,对于list [1, 2, 3, 4, 5, 6, 7, 8, 9]
        # 如果希望把list的每个元素都作平方,就可以用map()函数:
        def f(x):
           return x*x
        print(list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
        # 配合匿名函数使用:
        data = list(range(10))
        print(list(map(lambda x: x * x, data)))
    14、map函数案列2
        map()
        li = [1,2,3]
        data = map(lambda x:x*2,li)
        print(type(data))
        data = list(data)
        print(data)
  • 相关阅读:
    【原创】【JNI】OPUS压缩与解压的JNI调用(.DLL版本)
    线性基学习笔记
    杜教筛&Min_25筛学习笔记
    LOJ2540 随机算法
    仙人掌&圆方树学习笔记
    CF487E Tourists
    BZOJ2125 最短路
    [SHOI2008]仙人掌图
    BZOJ4316 小C的独立集
    NOI2015 品酒大会
  • 原文地址:https://www.cnblogs.com/renyz/p/11537424.html
Copyright © 2020-2023  润新知