Python基础-16 函数高级(续)
文章目录
- 十六、函数高级(续)
- 8. 函数返回多个值
- 9. 函数嵌套调用及过程
- - 函数嵌套
- - nonlocal 关键字
- 10. 递归函数的调用及过程(了解)
- 1. 系统编程相关
- - pass
- - 无限循环
- - TODO 注释
- **练习——函数版学生管理系统
- 退出函数exit()
- - 代码实现
- 12. 函数的引用,函数名的赋值及函数作参数传递
- - 将一个函数的引用赋值给变量
- - 函数作为参数传递
- 12. 匿名函数 lambda
- - 格式:
- - lambda定义和普通函数的区别:
- - 使用场景:
- 案例 - 计算器
- 不要滥用 `eval`
- 十七、高阶函数
- 1. map()函数
- - map()关系映射函数
- - 优化——利用lambda进行传参
- - 自定义实现map函数
- 2. reduce()函数
- - 使用
- - 应用——用reduce()求阶乘
- 3. filter()函数
- 4. sort()函数高级
十六、函数高级(续)
8. 函数返回多个值
当在函数中,需要返回多个值的情况下,可以在return 后面直接将多个值写出来
解释器在返回时,会将多个值自动进行组包
9. 函数嵌套调用及过程
- 函数嵌套
函数嵌套是指,在一个函数的函数体内,又去调用了另外一个函数
如果函数内调用了另一个函数,那么当前函数会中断执行,跳转到另一个函数位置进行执行,被调用执行结束后,才回到当前函数恢复中断,继续执行
无论函数如何调用: 谁调用函数,被调用函数执行完就返回到谁那去
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n3hyJq00-1610720718257)(Media/Xnip2019-04-19_10-08-38.png)]
一般在什么情况下使用嵌套函数?
- 封装:数据隐藏 外部无法访问“嵌套函数”。
- 贯彻 DRY(Don’t Repeat Yourself) 原则 嵌套函数,可以让我们在函数内部避免重复代码。
- 闭包:Enclosed 指的是嵌套函数(一个函数包裹另一个函数,闭包)
- LEGB规则中有提到闭包概念
- nonlocal 关键字
- nonlocal 用来声明外层的局部变量。
- global 用来声明全局变量。
def outer():b = 10def inner():nonlocal b # 申明外部函数的局部变量print('inner:', b)b = 20inner()print('outer b:', b)outer()
用于函数嵌套
10. 递归函数的调用及过程(了解)
递归调用是一种特殊的嵌套调用,即一个函数 内部 调用自己
本质就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。比如:
- 斐波那契数列的计算
- 汉诺塔
- 快排等问题
递归结构包括两个部分:
- 定义递归头
- 什么时候不调用自身方法。如果没有头,将陷入死循环,也就 是递归的结束条件。
- 递归体
- 什么时候需要调用自身方法。
递归步骤
- 把第 n 步的值和第 n-1 步相关联。
代码特点
- 函数内部的 代码 是相同的,只是针对 参数 不同,处理的结果不同
- 当 参数满足一个条件 时,函数不再执行
- 这个非常重要,通常被称为递归的出口,否则 会出现死循环!
- 一般用于返回值,不再调用自己。
注意,递归的缺陷
递归函数由于会创建大量的函数对象、过量的消耗内存和运算能力。在处理大量数据时,谨 慎使用。
应用:
# 阶乘
def factorial(n):if n == 1:return 1return n * factorial(n-1)print(factorial(5))'''过程
factorial(5) -> 5 * factorial(4) -> reutrn 5 *(4 * 3 * 2 * 1) -> 120-> 4 * factorial(3) -> return 4 *(3 * 2 * 1)-> 3 * factorial(2) -> reutrn 3 *(2 * 1)-> 2 * factorial(1) -> return 2 *(1)-> return 1
'''
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FakUllxx-1610720718259)(Media/image-20210103182805468.png)]
# 数字累加
def sum_numbers(num):if num == 1:return 1# 假设 sum_numbers 能够完成 num - 1 的累加temp = sum_numbers(num - 1)# 函数内部的核心算法就是 两个数字的相加return num + tempprint(sum_numbers(2))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aEfes7QZ-1610720718261)(media/002_递归调用示意图.png)]
提示:递归是一个 编程技巧,初次接触递归会感觉有些吃力!在处理 不确定的循环条件时,格外的有用,例如:遍历整个文件目录的结构
1. 系统编程相关
- pass
pass
就是一个空语句,不做任何事情,一般用做占位语句- 是为了保持程序结构的完整性
- 无限循环
- 在开发软件时,如果 不希望程序执行后 立即退出
- 可以在程序中增加一个 无限循环
- 由用户来决定 退出程序的时机
- TODO 注释
- 在
#
后跟上TODO
,用于标记需要去做的工作
# TODO(作者/邮件) 显示系统菜单
**练习——函数版学生管理系统
这个程序要理解记住的是逻辑,而不是代码
(个人)需要记住
def search_stu_with_id(stu_id):# 遍历每个学生for stu in students:if stu['id'] == stu_id:return stu# 返回没找到else:print(f'学号为{stu_id}的学生不存在')return 0
这里的for-else使用:当遍历完成,即没有return stu时,执行else后的语句
退出函数exit()
exit(0) # 程序通过 exit() 方法,可以直接结束程序
- 退出码
0
:- 这里的
0
代表退出程序后显示的数字 0
一般代表正常退出
- 这里的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RBCJFYtC-1610720718267)(Media/image-20201229203007345.png)]
- 代码实现
'''
学生管理系统程序 分析:1. 学生怎么表示2. 学生可能使用 学号 id ,姓名 name, 年龄 age ,可以使用一个字典来表示每一个学生3. 应该有一个容器去保存所有的学生字典 ,可以使用列表实现4. 应该有一个主控函数5. 菜单函数5-1. 选择功能的函数6. 添加学生函数7. 修改学生函数8. 查找学生函数9. 删除学生函数10.显示所有学生的函数11. 因为创建 学生和修改学生,都需要从键 盘输入 数据,那么输入 数据这个功能 就可以提取出一个函数,返回输入的数据12. 添加 一个功能 函数,用来显示每个学生的信息
'''# 1. 定义一个学生的列表,用来保存来管理学生students = []# 2. 主控函数def main():# 通过 死循环控制程序可以重复运行while True:# 显示菜单show_menu()# 键盘输入选择一个功能select_id = input('请输入一个功能id:')# 根据输入调用相应的功能 函数operator(select_id)def show_menu():print("---------------------------")print(" 学生管理系统 V1.0")print(" 1:添加学生")print(" 2:删除学生")print(" 3:修改学生")print(" 4:查询学生")print(" 5:显示所有学生")print(" 6:退出系统")print("---------------------------")# 参数是传递的用来选择的功能 id
def operator(select_id):if select_id == '1':add_stu()elif select_id == '2':stu_id = input('请输入要删除的学生id:')del_stu(stu_id)elif select_id == '3':modify_id = input('请输入要修改的学生id:')modify_stu(modify_id)elif select_id == '4':stu_id = input('请输入要查找的学生id:')stu = search_stu_with_id(stu_id)show_stu_info(stu)elif select_id == '5':show_all_info()elif select_id == '6':exit(0)else:print('输入错误,请重新输入')# break # 因为选择功能没有在循环中,所以不能break# return # 作用同上,函数返回后,返回到调用处,返回到主控函数中的死循环中,所以程序还是不能结束# 程序通过 exit() 方法,可以直接结束程序# 实现一个输入函数
# 用来从键盘获取学生信息,并返回
# 学号 id ,姓名 name, 年龄 age
def input_stu_info():# 保存输入的学生信息print('请输入学生信息:')id = input('请输入学号 id:')name = input('请输入姓名 name:')age = input('请输入年龄 age:')# 同时返回多个数据时,会组包成一个元组stu = id, name, agereturn stu# 实现 添加函数
def add_stu():# 主体思路 就是向列表 中添加 一个字典# 创建一个学生字典 ,空的stu_dict = {}# 调用 输入函数,获取学生信息stu_tup = input_stu_info()# 利用获取的信息为字典添加数据stu_dict['id'] = stu_tup[0]stu_dict['name'] = stu_tup[1]stu_dict['age'] = stu_tup[2]# 将字典加到列表中global studentsstudents.append(stu_dict)# print(stu_list)# 实现学生查找的功能
# 返回被找到的学生
def search_stu_with_id(stu_id):# 遍历每个学生for stu in students:if stu['id'] == stu_id:return stu# 返回没找到else:print(f'学号为{stu_id}的学生不存在')return 0# 实现一个用来显示 单个学生信息的函数
def show_stu_info(stu):if stu != 0:print(f'学号:{stu["id"]},姓名:{stu["name"]},年龄:{stu["age"]}')# 实现删除学生的函数
def del_stu(del_id):# 找到要删除的学生stu_dict = search_stu_with_id(del_id)# 从列表中删除if stu_dict == 0:print('删除失败')else:students.remove(stu_dict)print('删除成功')# 实现 修改学生的函数
def modify_stu(modify_id):# 查找学生stu = search_stu_with_id(modify_id)# 如果找到就修改if stu == 0:print('修改失败')else:del_stu(modify_id)add_stu()print('修改成功')# 先去调用 输入 函数获取数据# 利用获取的信息为字典添加数据# 显示所有学生信息
def show_all_info():# 遍历打印for stu in students:show_stu_info(stu)# 执行主控函数,运行程序
main()
12. 函数的引用,函数名的赋值及函数作参数传递
- 将一个函数的引用赋值给变量
def show():print('hello python')show()#将一个函数的引用赋值给变量func = show # 注意这里不能加'()',因为加了括号代表调用执行这个函数
print(func) # 输出:<function show at 0x000002880AA041F8>func() # 调用了show()
- 注意这里不能加
()
,因为加了括号代表调用执行这个函数 - 同样可以通过新的
变量名()
,来调用这个函数 - 作用:可以实现一个可以调用另外一个函数的函数
# 可以实现一个可以调用另外一个函数的函数
def show():print('hello python')def call_function(func):func()
call_function(show) # show不带括号
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WjIOwpCa-1610720718270)(Media/Xnip2019-04-20_09-58-21.png)]
- 函数作为参数传递
函数作为参数传递时,同样不需要加括号,只需传递函数名即可
因为如果加了括号,定于是运行了这个函数
12. 匿名函数 lambda
def 函数名(参数列表):
函数体
- 格式:
变量 = lambda [形参1], [形参2], ... : 函数体只能是 [单行表达式] 或 [函数调用]
func = lambda: 1 + 1
print(func) # <function <lambda> at 0x0000022D46A540D8>
print(func()) # 2func = lambda x: print(x ** 10)
func(2) # 1024
- lambda定义和普通函数的区别:
- lambda 没有函数名
- lambda 参数列表外没有括号
- lambda 函数体中,只能实现简单的表达式计算或函数调用
- lambda 函数体中,不能使用Return,if,while,for-in 这些都不行
- return:lambda函数默认返回表达式的计算结果,不需要return
- lambda 函数体中,可以使用if 实现的三目运算符.
func = lambda m, n: m if m > n else n
print(func(1, 2)) # 2
- 使用场景:
一般情况下,因为lambda的局限性,使得他不能实现复杂功能,只能实现一些简单功能
那么在使用时,一般会实现一个简单的,一次性使用的场景
eval
函数
功能:
eval()
- 将字符串 当成 有效的表达式 来求值 并返回计算结果
- 或将字符串当成有效代码来执行
语法:
eval(source[, globals[, locals]]) -> value
参数:
- source:一个 Python 表达式或函数 compile()返回的代码对象
- globals:可选。必须是 dictionary
- locals:可选。任意映射对象
# 基本的数学计算
In [1]: eval("1 + 1")
Out[1]: 2# 字符串重复
In [2]: eval("'*' * 10")
Out[2]: '**********'# 将字符串转换成列表
In [3]: type(eval("[1, 2, 3, 4, 5]"))
Out[3]: list# 将字符串转换成字典
In [4]: type(eval("{'name': 'xiaoming', 'age': 18}"))
Out[4]: dict
s = "print('abcde')"
eval(s) # abcdea = 10
b = 20
c = eval("a+b")
print(c) # 30dict1 = dict(a=100,b=200)
d = eval("a+b",dict1)
print(d) # 300
案例 - 计算器
需求
提示用户输入一个 加减乘除混合运算
返回计算结果
input_str = input(“请输入一个算术题:”)
print(eval(input_str))
不要滥用 eval
eval 函数会将字符串当做语句来执行,因此会被注入安全隐患。比如:字符串中含有删除文 件的语句。那就麻烦大了。因此,使用时候,要慎重!!!
在开发时千万不要使用
eval
直接转换input
的结果
__import__('os').system('ls')
等价代码
import os
os.system(“终端命令”)
执行成功,返回 0
执行失败,返回错误信息
十七、高阶函数
1. map()函数
- map()关系映射函数
map()
:会根据提供的函数对指定序列做映射
my_list = [i for i in range(5)]
print(my_list) # [0, 1, 2, 3, 4]# 这个函数是为了给map的参数进行传参
# 所以这个函数有且只能有一个参数
def f(x):return x ** 2result = map(f, cl)
print(type(result)) # <class 'map'>
print(result) # <map object at 0x000001FB8931F088>
print(list(result)) # [0, 1, 4, 9, 16]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GFf3pfOX-1610720718272)(Media/IMG_1138(20201230-112433)].JPG)
- 优化——利用lambda进行传参
# 利用lambda替代函数进行传参
my_list = [1, 2, 3, 4, 5]
result = map(lambda x: x ** 2, my_list)
print(type(result)) # <class 'map'>
print(result) # <map object at 0x000001DE3C291048>
print(list(result)) # [1, 4, 9, 16, 25]
- 自定义实现map函数
# 自定义实现map函数def my_map(func, c_list):result = []for i in c_list:result.append(func(i))return resultmy_list = [1, 2, 3, 4, 5]
result = my_map(lambda x: x ** 2, my_list)
print(type(result)) # <class 'map'>
print(result) # <map object at 0x000001DE3C291048>
print(list(result)) # [1, 4, 9, 16, 25]
2. reduce()函数
- 使用
reduce()
:函数会对参数序列中的元素进行累计
函数将一个数据集合中的所有数据进行下列操作
- 用传给reduce中的函数function(有两个参数)先对集合中的第1,2个元素进行操作
- 得到的结果在于第三个数据用function函数运算,最后得到一个结果
import functoolsmy_list = list('hello') # ['h', 'e', 'l', 'l', 'o']result = functools.reduce(lambda s1, s2: s1 + s2, my_list)
print(result) # 'hello'
- 应用——用reduce()求阶乘
# 练习——使用reduce求阶乘import functoolsmy_list = [i for i in range(1, 6)] # [1, 2, 3, 4, 5]result = functools.reduce(lambda s, n: s * n, my_list)
print(result) # 120
3. filter()函数
filter()
:用于过滤序列,过滤掉不符合调价按的元素,返回一个filter对象
- 如果要转换为列表,可以使用list()来转换
# 过滤偶数
my_list = [i for i in range(1, 11)] # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]new_list = list(filter(lambda x: x % 2 == 0, my_list))
print(new_list) # [2, 4, 6, 8, 10]
# 过滤出所有的数字字符串
my_list = ['123', '234', 'abc', '@#$', ' ', 'abc234', '132abc']
num_list = list(filter(lambda s: s if s.isdigit() else None, my_list))
print(num_list) # ['123', '234']
4. sort()函数高级
通过lambda指定key,根据key值对列表中的字典进行排序
my_list.sort(key=lambda d: d[‘id’])
my_list = [{'id': 3, 'name': 'Tom', 'age': 18},{'id': 1, 'name': 'Jack', 'age': 21},{'id': 2, 'name': 'Rose', 'age': 20}
]print(my_list)
# [{'id': 3, 'name': 'Tom', 'age': 18},
# {'id': 1, 'name': 'Jack', 'age': 21},
# {'id': 2, 'name': 'Rose', 'age': 20}]my_list.sort(key=lambda d: d['id'])
print(my_list)
# [{'id': 1, 'name': 'Jack', 'age': 21},
# {'id': 2, 'name': 'Rose', 'age': 20},
# {'id': 3, 'name': 'Tom', 'age': 18}]# 年龄降序排序
my_list.sort(key=lambda d: d['age'], reverse=True)
print(my_list)
# [{'id': 1, 'name': 'Jack', 'age': 21},
# {'id': 2, 'name': 'Rose', 'age': 20},
# {'id': 3, 'name': 'Tom', 'age': 18}]
Python基础-16 函数高级(续)相关推荐
- python的用途实例-Python基础之函数原理与应用实例详解
本文实例讲述了Python基础之函数原理与应用.分享给大家供大家参考,具体如下: 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体 ...
- Python基础之函数
详情请戳 python基础之函数介绍及使用 python基础之内置函数 python基础之迭代器和生成器 python基础之装饰器 转载于:https://www.cnblogs.com/zhangl ...
- Python数据结构与算法(1.5)——Python基础之函数与异常
Python数据结构与算法(1.5)--Python基础之函数与异常 0. 学习目标 1. 函数 1.1 自定义函数 1.2 函数与参数 1.3 函数与返回值 2. 异常处理 2.1 raise 语句 ...
- 第七篇 python基础之函数,递归,内置函数
阅读目录 一 数学定义的函数与python中的函数 二 为何使用函数 背景提要 三 函数和过程 四 函数参数 五 局部变量和全局变量 六 前向引用之'函数即变量' 七 嵌套函数和作用域 八 递归调用 ...
- python基础和第三方库 笔记(python基础完结包括高级用法,第三方库持续更新中...)
python基础 注:本笔记面向有一定基础的人 本笔记是本人快速复习python过程中记录的,不适合零基础的人学习python的主工具,可以作为辅工具,本笔记记录了入门阶段常用操作,如有错误的地方,希 ...
- 刻意练习:Python基础 -- Task05. 函数与Lambda表达式
背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...
- python基础十 函数(下)匿名函数、高阶函数、闭包、装饰器
目录 1. 匿名函数(lambda表达式) 2. 高阶函数 3. 函数的嵌套 4. nonlocal 关键字使用 5. 闭包 6. 装饰器 1. 匿名函数(lambda表达式) 简介 用一句话来表达只 ...
- python入门之函数调用内置函数_第九篇 python基础之函数,递归,内置函数
阅读目录 一 数学定义的函数与python中的函数 二 为何使用函数 背景提要 三 函数和过程 四 函数参数 五 局部变量和全局变量 六 前向引用之'函数即变量' 七 嵌套函数和作用域 八 递归调用 ...
- python基础学习——函数和方法的区别与联系
以下是综合多家说法的个人理解总结,仅为做到理解它们的区别与联系,不保证严谨. 函数 函数是封装了一些独立的功能,可以直接调用,python内置了许多函数,同时可以自建函数来使用. 独立的函数是函数(像 ...
最新文章
- 快慢指针____函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移
- 浅谈如何学习深度学习(经验之谈,仅供参考)
- ArcGIS Python
- vs2013 编译libevent32和64bit
- 大数据之-Hadoop3.x_MapReduce_WordCount编写_Reducer---大数据之hadoop3.x工作笔记0090
- C++的multi_map如何输出所有key值相等的元素
- eclipse安装SVN插件(2020最新,亲测可用)
- 运维工程师项目案例_要建设AIOps,运维工程师的角色和职责需如何调整?
- Kubernetes_MindMap
- 陌生人社交已成主流,“灵魂”社交软件Soul的上市之忧
- [异常检测] Regularity Learning via Explicit Distribution Modeling for Skeletal Video Anomaly Detection
- Data-driven methods for solving algebra word problems论文阅读
- LaTex - PPT 换页动态效果(亲测有效)
- Life feelings--8--愉悦的做技术--将实验当做一种快乐
- 【POJ3093】Margaritas on the River Walk【01背包变种】
- Codeforces 439 A. Devu, the Singer and Churu, the Joker
- 1085 PAT单位排行 (25分)-PAT乙级真题-C++实现
- fgo7.27服务器维护,命运冠位指定2020年7月13日活动维护公告
- 设计心理学读后的随想
- Android面试题整理(源自鸿洋大神公众号【201803】的一篇BAT面试题推送)