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("\033[31;1m找的数在middle[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)
        else:  # 找的数在middle右面
            print("\033[32;1m找的数在middle[%s]右面\033[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)

 

posted @ 2019-09-17 21:44  Wolf_Coder  阅读(379)  评论(0编辑  收藏  举报