目录

Python基础语法(16)函数加强练习

Python基础语法(16)函数加强练习

学习目标

  • 应用:学员管理系统
  • 递归
  • lambda表达式
  • 高阶函数

应用:学员管理系统

需求:进入系统显示系统功能界面,功能如下:

  • 1、添加学员
  • 2、删除学员
  • 3、修改学员系统
  • 4、查询学员系统
  • 5、显示所有学员信息
  • 6、退出系统

六个功能,用户根据自己需求选取。

步骤分析

  1. 显示功能界面,用print打印
  2. 用户输入功能序号,用input函数
  3. 根据用户输入的功能序号,执行不同的功能,不同的功能可以封装进不同的函数。(定义函数+调用函数)

需求框架实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
'''
1、显示功能界面菜单
2、用户输入功能序号
3、根据输入的序号执行不同的功能
'''
def print_info():
    print("-" * 20)
    print("1.添加学员")
    print("2.删除学员")
    print("3.修改学员")
    print("4.查询学员")
    print("5.显示所有学员信息")
    print("6.退出系统")
    print("-" * 20)
while True:
    # 显示菜单
    print_info()
    # 输入序号
    user_num = int(input("请输入功能序号:"))

    # 输入序号判断不同的功能
    if user_num == 1:
        print("添加")
    elif user_num == 2:
        print("删除")
    elif user_num == 3:
        print("修改")
    elif user_num == 4:
        print("查询")
    elif user_num == 5:
        print("显示")
    elif user_num == 6:
        print("系统已退出")
        break
    else:
        print("输入功能有误")

各功能的细节实现

所有的功能函数都是操作学员的信息,所以存储所有学员信息应该是一个全局变量,数据类型最好为列表,每个学生的信息包含学生的姓名,学号和年龄等,因此数据为字典

添加学员

  • 需求分析:

    • 接收用户输入学员的信息,并保存。
    • 判断是否添加学员信息:如果姓名存在,则报错不添加,如果姓名不存在,则准备空字典,将用户输入的数据追加到字典,在列表追加字典数据。
    • 在框架中的if中调用此函数。
  • 代码实现:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    def add_stu():
        """
        添加学员信息的函数
        :return:
        """
        new_name = input("请输入姓名:")
        new_id = input("请输入学号:")
        new_age = input("请输入年龄:")
        global all_info
        # 存在重名,则不添加,并报错
        for i in all_info:
            if new_name == i['name']:
                print('此学员已存在')
                return
        # 不存在重名,则准备字典,将数据追加到字典,列表在追加字典。
        added_dict = {}
        added_dict["id"] = new_id
        added_dict["name"] = new_name
        added_dict["age"] = new_age
      
        all_info.append(added_dict)
        print(all_info)
    

删除学员

  • 需求分析:

    • 用户输入姓名来查找待删除的学员。
    • 检查是否存在,存在则从列表删除这个数据;不存在则提示不存在。
    • 对相应位置的if调用该函数。
  • 代码实现:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    def modify_stu():
        """
        修改学员信息的函数
        :return:
        """
        global all_info
        name = input("请输入要修改学员姓名:")  # 用户输入姓名来查找学员
        for i in all_info:
            if name == i['name']:   # 存在则开始修改
                i['name'] = input("请输入新的姓名:")
                i['id'] = input(f"请输入{i['name']}新的学号:")
                i['age'] = input(f"请输入{i['name']}新的年龄:")
                print(f"修改完成,{i['name']}的年龄是{i['age']}岁,学号为:{i['id']}")
                break   # 不再遍历余下的学员信息
        else:   # 未发生修改时的操作
            print("此学员未查找到!")
    

修改学员信息

  • 需求分析:

    • 用户输入姓名来查找待修改的学员。
    • 检查存在,如果存在则修改学员信息,不存在则提示不存在。
    • 对应位置if调用该函数。
  • 代码实现:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    def modify_stu():
        """
        修改学员信息的函数
        :return:
        """
        global all_info
        name = input("请输入要修改学员姓名")  # 用户输入姓名来查找学员
        for i in all_info:
            if name == i['name']:   # 存在则开始修改
                i['name'] = input("请输入新的姓名:")
                i['id'] = input(f"请输入{i['name']}新的学号")
                i['age'] = input(f"请输入{i['name']}新的年龄")
                print("修改完成")
                break   # 不再遍历余下的学员信息
        else:   # 未发生修改时的操作
            print("此学员未查找到!")
    

查询学员信息:

  • 需求分析:

    • 用户输入待查询学员姓名。
    • 检查学员是否存在,存在则打印该学员的信息,不存在提示不存在。
    • 对应位置if调用该函数。
  • 代码实现:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    def search_stu():
        '''
        查询学生信息的函数
        :return: 
        '''
        global all_info
        name = input("请输入待查询的学生姓名:")  # 用户输入姓名来查找学员
        for i in all_info:
            if name == i['name']:   # 存在则开始查询
                print(f"{i['name']}的年龄是{i['age']},学号是{i['id']}")
                break   # 不再遍历余下的学员信息
        else:   # 未发生修改时的操作
            print("此学员未查找到!")
    

显示所有的学员信息:

  • 需求分析:如果存在学员信息,则遍历所有的学员信息,直接打印,如果不存在信息则添加信息。

  • 代码实现:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    def show_stu():
        """
        打印存储好的所有学员信息的函数
        :return:
        """
        global all_info
        if all_info != []:
            for i in all_info:
                print(f"姓名:{i['name']}\t年龄:{i['age']}\t学号:{i['id']}")
        else:
            print('无任何学员信息,请添加学员')
            add_stu()
    

递归

递归的应用场景

递归是一种编程思想,其应用场景:

  1. 在我们日常开发中,如果要遍历一个文件夹下面所有的文件,通常会使用递归来实现。
  2. 在后续的算法课程中,很多算法离不开递归,如快速排序等。

递归的特点

  1. 函数内部自己调用自己
  2. 递归必须要有出口

递归应用:3以内的数字累加和

1
2
3
4
5
6
7
8
def add_sum(num):
    # 如果是1 直接返回1 -- 出口
    if num == 1:
        return 1
    return num + add_sum(num-1) # 如果不是1 重复执行累加并返回结果

result = add_sum(3)
print(result)

代码理解:

当函数调用时,函数即触发开始执行,参数3传入函数形参位置进行执行,首先判断if不满足条件,执行函数最后一句return语句,其中又遇到函数调用,且实参-1为2传入参数再进行函数的执行,判断if不满足条件后开始执行最后一句return语句,遇到函数调用时进行再一次的2-1 = 1参数传入函数的执行,符合if条件,return语句生效返回的1给到上一次函数调用的位置,即返回了2+1,2+1又返回到第一次函数调用的位置,即返回了3+2+1。

⚠️注意:若没有判断递归出口,即会报错“超出最大递归深度”,不同计算机的深度都不一样,不会像循环一样死循环一直执行。


lambda表达式(匿名函数)

应用场景

lambda表达式可以简化代码,如果一个函数只有一个返回值,并且只有一句代码,可以使用lambda表达式。

语法

1
lambda 参数列表(这个可有可无):表达式
  • lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用。
  • lambda表达式能接受任何一个参数但只能返回一个表达式的值。
1
2
3
a = lambda : 'aaa'
print(a)		# <function <lambda> at 0x7fded7a79670>打印的是函数内存地址
print(a())	# 调用这个函数

⚠️注意:打印函数名时,打印的是函数的内存地址;打印函数调用时,打印的才是函数的返回值。

案例:两数之和

1
2
3
4
5
6
def two_sum(a,b):
    return a+b
print(two_sum(1,9))	# 10

b = lambda a,b:a+b	# 给匿名函数一个名字叫b
print(b(12,23))	# 35

lambda表达式参数形式

lambda表达式的参数写法和定义函数的写法差不多:分为无参数、有一个参数、缺省(默认)参数、可变位置参数*args,不定长关键字参数**kwargs。

无参数:

1
2
fn1 = lambda:100
print(fn1()) 	# 100

一个参数,位置参数:

1
2
fn2 = lambda a:a+1
print(fn2(2))	# 3

缺省(默认)参数:

1
2
3
fn3 = lambda a,b,c=100:a+b+c
print(fn3(1,2))	# 103
print(fn3(1,2,3))	# 6

可变位置参数*args:

1
2
3
4
fn4 = lambda *args:args
print(fn4('adasdads',12313))	# ('adasdads', 12313) 返回形式为一个元组
print(fn4())	# ()
print(fn4(1))	# (1,)

不定长关键字参数**kwargs:

1
2
3
fn5 =  lambda **kwargs:kwargs
print(fn5(a = 222, b = 'aaaa' ,c = 100))	# {'a': 222, 'b': 'aaaa', 'c': 100}
print(fn5())	# {}

lambda的应用

带判断的lambda:

1
2
fn6 = lambda a,b:b if a > b else a		# 三元表达式
print(fn6(2,5))	# 两个数字比大小,谁小返回谁。

列表数据按字典key值进行排序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
students = [
    {'name': 'g', 'age': 35},
    {'name': 'a', 'age': 21},
    {'name': 'b', 'age': 25},
    {'name': 'd', 'age': 35},
]
students.sort(key=lambda x:x['name'])       # 升序排序
print(students)
students.sort(key=lambda x:x['name'],reverse=True)     #降序排序
print(students)

高阶函数

高阶函数的定义:把函数作为另一个函数的参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现,函数式编程就是这种高度抽象的编程范式。

abs()绝对值函数:

1
print(abs(-11111))		# 11111

round四舍五入函数:

1
print(round(1.23))	# 1

需求:任意两个数字,按照指定要求整理数字再进行求和计算。(如先求绝对值再求和)

方法一:

1
2
3
4
def add_num(a,b):
    return abs(a)+abs(b)	# 这里吧函数的功能写死了 只能求绝对值后求和
result = add_num(-22,33)
print(result)

方法二:

1
2
3
4
5
def add_num(a,b,f):	# f接收用来传入的函数
  return f(a)+f(b)
result1 = add_num(12,-22,abs) # 可以用来计算绝对值的和
result2 = add_num(1.23,2.68,round)	# 可以用来计算程序四舍五入后的和
print(result1,result2)	# 34 4

⚠️注意:两种方法对比,发现方法2的代码更简洁,函数灵敏性更高,功能更灵活。

函数式编程大量使用函数,减少了代码的重复,提高了开发速度

内置高阶函数

  • map( )

map(func, lst),将传入的函数变量func作用到lst变量的每个元素中,并将结果组成新的列表(Py2)/迭代器(Py3)返回。

需求:计算list1序列中各个数字的平方。

1
2
3
4
5
6
list1 = [1,2,3,4,5]
def func(x):
  return x**2
result = map(func,list1)
print(result)   # 打印<map object at 0x7fa9dd9f2f10> 迭代器地址
print(list(result)) # 迭代器转为列表打印
  • reduce( )使用此函数要导入functools模块

reduce(func, lst),将传入的函数变量值func每次计算的结果和序列lst下一个元素做积累计算func函数必须接受两个参数

需求:计算列表中的数字和。

1
2
3
4
5
6
import functools
list = [1,2,3,4,5]
def func(a,b):
  return  a+b
result = functools.reduce(func,list)
print(result)     # 15
  • filter( )

filter(func,lst)函数用于过滤序列,过滤掉不符合条件的元素,返回一个filter对象,如果转换为列表则使用list()函数。

1
2
3
4
5
6
list1 = [1,2,3,4,5,6,7]
def func(x):
  return x+1
result = filter(func,list1)
print(result)   # <filter object at 0x7fccf020af10>
print(list(result))   # [2, 4, 6]

总结

  • 递归
    • 作用:简化代码完成重复迭代的操作。
    • 递归的特点有两个一个是递归是函数在定义时自己调用自己,函数必须要有一个出口
    • 若没有出口则会报错超出最大递归深度不会像循环一样陷入死循环,每个计算机的递归深度都有所不同。
  • lambda表达式
    • 也叫匿名函数,也可以进行代码的简化;
    • 如果函数只有一个返回值,且只有一句操作代码,则可以使用lambda表达式来简化代码;
    • 语法是lambda 函数参数:表达式,参数可有可无,但是返回值只允许一个表达式的值
    • 匿名函数需要赋值给变量名才能使用,打印时只打印变量名会显示地址,打印函数调用时才能显示返回值内容。
    • lambda参数有几种情况:1.无参数、2.一个或者多个位置参数、3.默认(缺省)参数、4.不定长位置参数、5.不定长关键字函数。
  • 高阶函数
    • 作用:把函数作为参数传入,简化代码。def func(a,b,c)c可以用来传递定义好的函数名。
    • 内置的高阶函数有:
      • map(func,lst):将lst中的每个元素作用于func函数并将结果组成为一个新的列表(py2)/迭代器(py3)返回。
      • reduce(func,lst):引入functools模块,作用是将传入func函数的两个参数(来源于lst中前两个元素)每次计算的结果,与lst中的下一个元素进行累计计算,func函数必须定义有两个形参
      • filter(func,lst)函数用于过滤序列,过滤掉lst中不符合条件的元素,返回一个filter对象,可用list强制转换函数进行打印显示。