文章目录

  • 十六、函数高级(续)
    • 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)]

一般在什么情况下使用嵌套函数?

  1. 封装:数据隐藏 外部无法访问“嵌套函数”。
  2. 贯彻 DRY(Don’t Repeat Yourself) 原则 嵌套函数,可以让我们在函数内部避免重复代码。
  3. 闭包: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 步相关联。

代码特点

  1. 函数内部的 代码 是相同的,只是针对 参数 不同,处理的结果不同
  2. 参数满足一个条件 时,函数不再执行
    • 这个非常重要,通常被称为递归的出口,否则 会出现死循环
    • 一般用于返回值,不再调用自己。

注意,递归的缺陷

递归函数由于会创建大量的函数对象、过量的消耗内存和运算能力。在处理大量数据时,谨 慎使用。

应用:

# 阶乘
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定义和普通函数的区别:

  1. lambda 没有函数名
  2. lambda 参数列表外没有括号
  3. lambda 函数体中,只能实现简单的表达式计算或函数调用
  4. lambda 函数体中,不能使用Return,if,while,for-in 这些都不行
    • return:lambda函数默认返回表达式的计算结果,不需要return
  5. lambda 函数体中,可以使用if 实现的三目运算符.
func = lambda m, n: m if m > n else n
print(func(1, 2))  # 2

- 使用场景:

一般情况下,因为lambda的局限性,使得他不能实现复杂功能,只能实现一些简单功能
那么在使用时,一般会实现一个简单的,一次性使用的场景

  1. 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

案例 - 计算器

需求

  1. 提示用户输入一个 加减乘除混合运算

  2. 返回计算结果

    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():函数会对参数序列中的元素进行累计

函数将一个数据集合中的所有数据进行下列操作

  1. 用传给reduce中的函数function(有两个参数)先对集合中的第1,2个元素进行操作
  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 函数高级(续)相关推荐

  1. python的用途实例-Python基础之函数原理与应用实例详解

    本文实例讲述了Python基础之函数原理与应用.分享给大家供大家参考,具体如下: 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体 ...

  2. Python基础之函数

    详情请戳 python基础之函数介绍及使用 python基础之内置函数 python基础之迭代器和生成器 python基础之装饰器 转载于:https://www.cnblogs.com/zhangl ...

  3. Python数据结构与算法(1.5)——Python基础之函数与异常

    Python数据结构与算法(1.5)--Python基础之函数与异常 0. 学习目标 1. 函数 1.1 自定义函数 1.2 函数与参数 1.3 函数与返回值 2. 异常处理 2.1 raise 语句 ...

  4. 第七篇 python基础之函数,递归,内置函数

    阅读目录 一 数学定义的函数与python中的函数 二 为何使用函数 背景提要 三 函数和过程 四 函数参数 五 局部变量和全局变量 六 前向引用之'函数即变量' 七 嵌套函数和作用域 八 递归调用 ...

  5. python基础和第三方库 笔记(python基础完结包括高级用法,第三方库持续更新中...)

    python基础 注:本笔记面向有一定基础的人 本笔记是本人快速复习python过程中记录的,不适合零基础的人学习python的主工具,可以作为辅工具,本笔记记录了入门阶段常用操作,如有错误的地方,希 ...

  6. 刻意练习:Python基础 -- Task05. 函数与Lambda表达式

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  7. python基础十 函数(下)匿名函数、高阶函数、闭包、装饰器

    目录 1. 匿名函数(lambda表达式) 2. 高阶函数 3. 函数的嵌套 4. nonlocal 关键字使用 5. 闭包 6. 装饰器 1. 匿名函数(lambda表达式) 简介 用一句话来表达只 ...

  8. python入门之函数调用内置函数_第九篇 python基础之函数,递归,内置函数

    阅读目录 一 数学定义的函数与python中的函数 二 为何使用函数 背景提要 三 函数和过程 四 函数参数 五 局部变量和全局变量 六 前向引用之'函数即变量' 七 嵌套函数和作用域 八 递归调用 ...

  9. python基础学习——函数和方法的区别与联系

    以下是综合多家说法的个人理解总结,仅为做到理解它们的区别与联系,不保证严谨. 函数 函数是封装了一些独立的功能,可以直接调用,python内置了许多函数,同时可以自建函数来使用. 独立的函数是函数(像 ...

最新文章

  1. 快慢指针____函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移
  2. 浅谈如何学习深度学习(经验之谈,仅供参考)
  3. ArcGIS Python
  4. vs2013 编译libevent32和64bit
  5. 大数据之-Hadoop3.x_MapReduce_WordCount编写_Reducer---大数据之hadoop3.x工作笔记0090
  6. C++的multi_map如何输出所有key值相等的元素
  7. eclipse安装SVN插件(2020最新,亲测可用)
  8. 运维工程师项目案例_要建设AIOps,运维工程师的角色和职责需如何调整?
  9. Kubernetes_MindMap
  10. 陌生人社交已成主流,“灵魂”社交软件Soul的上市之忧
  11. [异常检测] Regularity Learning via Explicit Distribution Modeling for Skeletal Video Anomaly Detection
  12. Data-driven methods for solving algebra word problems论文阅读
  13. LaTex - PPT 换页动态效果(亲测有效)
  14. Life feelings--8--愉悦的做技术--将实验当做一种快乐
  15. 【POJ3093】Margaritas on the River Walk【01背包变种】
  16. Codeforces 439 A. Devu, the Singer and Churu, the Joker
  17. 1085 PAT单位排行 (25分)-PAT乙级真题-C++实现
  18. fgo7.27服务器维护,命运冠位指定2020年7月13日活动维护公告
  19. 设计心理学读后的随想
  20. Android面试题整理(源自鸿洋大神公众号【201803】的一篇BAT面试题推送)

热门文章

  1. java web应用实现扫码枪获取信息
  2. 如何编写高质量的易语言代码?
  3. 程序员数学(9)--不等式与不等式组
  4. vue3中组件给后代组件传值,provide和inject的使用
  5. Nexus环境安装部署及使用
  6. 【网络原理】一个数据包从发送到接收在网络中经历了那些过程(详细分析)
  7. 《牛客刷题》sql错题集
  8. 牛客网SQL刷题四-电商场景(某东商城)
  9. 【spring的使用方法】
  10. ICP算法MATLAB仿真