文章目录
-
- 前言
- 7. 公共操作
-
- 7.1 运算符
- 7.2 公共方法
- 7.3 容器类型转换
- 8. 推导式
-
- 8.1 列表推导式
- 8.2 字典推导式
- 8.3 集合推导式
- 8.4 推导式总结
- 9. Python函数
-
- 9.1 函数的使用
- 9.2 函数的说明文档
- 9.3 函数的嵌套调用
- 9.4 变量的作用域
- 9.5 函数返回值(多返回值)
- 9.6 函数的参数的类型
- 9.7 引用作实参
- 9.8 可变和不可变类型汇总
- 9.9 递归函数和匿名函数(lambda)
- 10. 学生管理系统
- 11. 高级函数
-
- 11.1 abs()和round()函数
- 11.2 内置高阶函数(map、reduce、filter)
前言
- 在Python基础(一)中,非常感谢大家的点赞、收藏、评论、关注。
- 在Python基础(二)中,尽量用简洁易懂的方式来梳理知识点。
- 如果对你的学习有帮助,点个赞支持一下,一键三连哦~
Python基础(一):https://blog.csdn.net/weixin_46818279/article/details/108576298
7. 公共操作
什么是公共操作那???
公共操作:数据序列基本上都支持的一些操作
7.1 运算符
运算符 | 描述 | 支持的容器类型 |
---|---|---|
+ | 合并 | 字符串、列表、元组 |
* | 复制 | 字符串、列表、元组 |
in | 元素是否存在 | 字符串、列表、元组、字典 |
not in | 元素是否存在 | 字符串、列表、元组、字典 |
运算符:+(合并的作用)
str1 = 'aa'
str2 = 'bb'
list1 = [1,2]
list2 = [10,20]
t1 = (1,2)
t2 = (10,20)
dict1 = { 'name':'tom'}
dict2 = { 'age':30}
# 1. + : 合并
print(str1+str2) # 输出 aabb
print(list1+list2) # 输出 [1, 2, 10, 20]
print(t1+t2) # 输出 (1, 2, 10, 20)
print(dict1+dict2) # 报错:字典不支持合并运算
运算符:*(复制的作用)
str1 = 'a'
list = ['hello']
t1 = ('world',)
# *:复制 支持字符串、列表、元组
print(str1 * 5) # 输出aaaaa
print('-' * 10) # 输出10个----------
print(list * 5) # 输出['hello', 'hello', 'hello', 'hello', 'hello']
print(t1 * 5) # 输出 ('world', 'world', 'world', 'world', 'world')
运算符:in、not in(判断元素是否存在)
str1 = 'abcd'
list1 = [10,20,30]
t1 = (100,200,300)
dict1 = { 'name':'Python', 'age':30}
# in 和 not in
# 1. 字符a是否存在
print('a' in str1) # 输出 True
print('a' not in str1) # 输出 false
# 2. 数据10是否存在
print(10 in list1) # 输出True
print(10 not in list1) # 输出False
# 3. 100是否存在
print(100 in t1) # 输出 True
print(100 not in t1) # 输出Fasle
# 4. name是否存在
print(dict1)
print('name' in dict1) # True
print('name' not in dict1) # False
print('name' in dict1.keys()) # True
print('name' in dict1.values() ) # False
7.2 公共方法
公共方法之len()、del()、max()、min()、range(start,end,step)、enumerate()
这六个函数的作用以及用法,举栗子说明
(1)len():计算容器中元素的个数
str1 = 'abcd'
list1 = [10, 20, 30]
t1 = (100, 200, 300)
dict1 = { 'name':'Python', 'age':30}
s1 = { 10 , 20}
# len() 计算容器中元素个数
print(len(str1)) # 输出4
print(len(list1)) # 输出3
print(len(t1)) # 输出3
print(len(dict1)) # 输出2
print(len(s1)) # 输出2
(2)del():删除
str1 = 'abcd'
list1 = [10, 20, 30]
t1 = (100, 200, 300)
dict1 = { 'name':'Python', 'age':30}
s1 = { 10 , 20}
# 1. del 目标 或者 del(目标)
# str1字符串
del str1 # 删除整个字符串
print(str1) # 报错说明已经删除成功
============================================================================
# list1 列表
del(list1)
print(list1) # 报错说明已经删除成功
# del(list1[0])
# print(list1) # 输出[20, 30]
# del list1[0]
# print(list1) # 输出[20, 30]
==============================================================================
# dict1 字典
del dict1
print(dict1) # 报错,已经删除成功
del dict1['name']
print(dict1) # 输出结果为 {'age': 30}
==============================================================================
# s1 集合
del s1
print(s1) # 报错,已经删除成功
(3) max():返回容器中元素最大值
min():返回容器中元素最小值
str1 = 'abcde'
list1 = [10, 20, 30]
# 1. max()最大值
print(max(str1)) # 输出e
print(max(list1)) # 输出30
# 2. min():最小值
print(min(str1)) # 输出a
print(min(list1)) # 输出10
(4)range():生成从start到end的数字,步长为step,供for循环使用
""" 注意事项: 1. 如果不写开始,默认从0开始 2. 如果不写步长,默认为1 """
print(range(1,10,1)) # 输出 range(1, 10),返回的是可迭代的对象,需要配合for循环才能拿到数字
for i in range(1,10,1):
# 遍历可迭代对象,并且拿到了对象内部的这些数字
print(i) # 输出的是1,2,3,4,5,6,7,8,9
for i in range(1,10):
print(i) # 如果不写步长,则默认步长是1
for i in range(1,10,2):
print(i) # 因为步长是2,所以输出1,3,5,7,9
for i in range(10):
print(i) # 这里的10代表结束。开始不写,默认从0开始。步长不写,默认为1。 但是不能不写结束!
(5)enumerate():函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用于在for循环当中。
# 1. 语法: enumerate(可遍历对象,start = 0)
# 2. start参数用来设置遍历数据的下标的起始值,默认为0
list1 = ['a', 'b', 'c', 'd', 'e']
# enumerate 返回结果是元组,元组第一个数据是原迭代对象的数据对应的下标,元组第二个数据是原迭代对象的数据
for i in enumerate(list1):
print(i)
''' 输出的结果为: (0, 'a') (1, 'b') (2, 'c') (3, 'd') (4, 'e') '''
for i in enumerate(list1,start = 1):
print(i)
''' 这时的start为1,输出的结果为: (1, 'a') (2, 'b') (3, 'c') (4, 'd') (5, 'e') '''
7.3 容器类型转换
直接上栗子:
# 已有的数据类型和程序想要的数据类型不一样,这个时候利用函数做类型的转换就可以了。
list1 = [10,20,30]
s1 = { 100, 200, 300}
t1 = ('a', 'b', 'c')
# tuple():将某个序列转换成元组
print(tuple(list1)) # 输出结果为(10, 20, 30)
print(tuple(s1)) # 输出结果为(200, 100, 300)
# list():转换成列表
print(list(s1)) # 输出结果为 [200, 100, 300]
print(list(t1)) # 输出结果为 ['a', 'b', 'c']
# set():转换成集合
print(set(list1)) # 输出结果为{10, 20, 30}
print(set(t1)) # 输出结果为{'c', 'b', 'a'}
''' 注意: 1. 集合可以快速完成列表去重 2. 集合不支持下标(因为没有顺序) '''
8. 推导式
推导式的作用:简化代码
列表推导式会返回一个列表 ,字典推导式会返回一个字典,集合推导式会返回一个集合
8.1 列表推导式
直接上代码:推导式如何简化代码的,如何使用推导式
''' 书写代码: 1. 创建空列表 2. 循环将有规律的数据写入到列表 方法实现: 1. 循环实现 2. 列表推导式(化简代码,创建或控制有规律的列表) 得出结论: 1. 列表推导式代码量最少,起到了简化代码的作用 '''
=========================================================================
# while 实现
list1 = []
i = 0
while i < 10:
list1.append(i)
i += 1
print(list1) # 输出结果为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
==========================================================================
# for 实现
# 用for实现比while实现所需的代码量少
list1 = []
for i in range(10):
list1.append(i)
print(list1) # 输出结果为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
==========================================================================
# 列表推导式实现
list1 = [i for i in range(10)] # 中括号里面第一个i,是接收数据的返回值,然后保存在列表中
print(list) # 输出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
再举个栗子:带if的列表推导式
# 需求:0-10偶数数据的列表
# 1. 简单的列表推导式,range()步长实现
list1 = [i for i in range(0,10,2)]
print(list1) # 输出结果为 [0, 2, 4, 6, 8]
# 2. for循环加if 创建有规律的列表
list2 = []
for i in range(10):
if i % 2 == 0:
list2.append(i)
print(list2)
# 3. 把for循环配合if的代码 改写 带if的列表推导式
list3 = [i for i in range(10) if i % 2 == 0]
print(list3)
再来个栗子:
''' 需求:创建列表如下:[(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)] 1. 用for循环嵌套的方法进能够解决 数据1:1 和 2 range(1,3) 数据2:0 1 2 用 range(3) 2. 用列表推导式解决:多for的列表推导式等同于for循环嵌套,就是去掉标点、回车符和缩进。 '''
# 1. 用for循环嵌套
list1 = []
for i in range(1,3):
for j in range(3):
# 列表里面追加元素:循环前准备一个空列表,然后这里追加元组数据到列表
list1.append((i,j))
print(list1) # 输出结果为[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 2. 多个for实现列表推导式
list2 = [(i,j) for i in range(1,3) for j in range(3)]
print(list2) # 输出结果为[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
经过上面这三个栗子,已经对推导式有一定的了解了,那么继续学习下面推导式的学习。
8.2 字典推导式
直接上栗子:
# 创建字典 key是1-4的数字,value是这个数字的平方
dict1 = { i: i**2 for i in range(1,5)}
print(dict1) # 输出 {1: 1, 2: 4, 3: 9, 4: 16}
再举个栗子:合并列表为字典
# 1. 长度一样的列表合并字典
# list1 = ['name', 'age', 'gender']
# list2 = ['tom', 20, 'man']
# dict1 = {list1[i]: list2[i] for i in range(len(list1))}
# print(dict1) # 输出的结果为 {'name': 'tom', 'age': 20, 'gender': 'man'}
# 长度不一样的列表合并成字典
list3 = ['name', 'age', 'gender', 'id']
list4 = ['tom', 20, 'man']
# 下面的语句会报错,因为不对等,如果取长的列表len(list3)则会报错
# dict1 = {list3[i]: list4[i] for i in range(len(list3))}
# 下面的语句才正确
dict2 = { list3[i]: list4[i] for i in range(len(list4))}
print(dict2) # 输出结果为{'name': 'tom', 'age': 20, 'gender': 'man'}
''' 总结: 1. 如果两个列表数据个数相同,len统计任何一个列表的长度都可以 2. 如果两个列表数据个数不同,len统计数据多的列表数据个数会报错,len统计数据少的列表数据个数不会报错 '''
再来个栗子:提取字典中的目标数据
counts = { 'MBP': 268, 'HP':125, 'DELL':201, 'Lenovo': 199, 'acer': 99}
''' 1. 需求:提取电脑台数大于等于200 获取所有键值对数据,判断v值大于等于200返回 '''
# 返回一个迭代器,内部是元组dict_items([('MBP', 268), ('HP', 'DELL'), ('Lenovo', 199), ('acer', 99)])
print(counts.items())
# 提取字典中目标数据,这个用法非常重要!!!
dict1 = { key:value for key,value in counts.items() if value >= 200}
print(dict1) # {'MBP': 268, 'DELL': 201}
8.3 集合推导式
这个用的不多,简单的来个栗子:
# 需求:创建一个集合,数据为下方列表的2次方
list1 = [1,1,2]
set1 = { i ** 2 for i in list1}
print(set1) # 输出 {1, 4}
# 集合有数据去重功能,所以这个集合数据只有两个数据,分别是1,4
8.4 推导式总结
三种推导式书写的格式
1. 列表推导式
[xx for xx in range]
2. 字典推导式
{ xx1 : xx2 for ... in ...}
3. 集合推导式
{ xx for xx in ...}
9. Python函数
Python函数的使用其实跟C、和Java函数的使用都是大同小异的。
函数的作用: 装代码,高效的代码重用
9.1 函数的使用
基本使用
# 1. 定义函数
def sel_func():
print('I Love Python')
# 2. 函数调用
print('恭喜你登录成功')
sel_func()
''' 注意 1. 不同的需求,参数可有可无 2. 在Python中,函数必须先定义后使用 3. 当调用函数的时候,解释器回到定义函数的地方去执行下方缩进的代码,当这些代码执行完, 回到调用函数的地方继续向下执行定义函数的时候,函数体内部缩进的代码并没有执行 '''
有参数的函数
函数的参数:函数调用的时候可以传入真实数据,增大函数的使用的灵活性
形参:函数定义时书写的参数(非真实数据)
实参:函数调用时书写的参数(真实数据)
# 参数形式传入真实数据,做加法运算
# 这里的a、b是形参
def add_num2(a,b):
result = a + b
print(result)
# 10,20是实参
add_num2(10,20) # 输出30
函数中return的作用
def buy():
return '烟'
# print('ok') #这一行代码不执行
goods = buy()
print(goods)
''' return 作用: 1. 负责函数返回值 2. 退出当前函数:导致return下方的所有代码(函数体内部)不执行 '''
9.2 函数的说明文档
就是自己书写函数的时候,可以在函数里写一个说明文档,以后通过这个说明文档可以直接查看这个函数什么作用。
# len是内置函数,早在定义的时候就已经封装好说明文档了
# 自己写的函数没有说明文档,为了方便后期查看这种解释说明的信息更快捷更方便,定义函数的同时,定义一个说明文档就可以了
# 函数内部缩进的第一行书写的多行注释才是说明文档。如果敲了回车,则会更详细的显示(参数和返回值)。
help(len) # help函数作用:查看函数的说明文档(函数解释说明的信息)
# def sum_num(a,b):
# ''' 求和函数 ''' # 定义函数的说明文档
# return a + b
# help(sum_num)
# 函数的说明文档的高级使用。 就是多行注释按回车,会出现参数1、2和renturn,说明他们的作用。
def sum_num1(a,b):
''' 求和函数sum_num1 :param a: 参数1 :param b: 参数2 :return: 返回值 '''
return a + b
help(sum_num1)
9.3 函数的嵌套调用
来个栗子感受一下嵌套调用
# 所谓函数嵌套调用指的是一个函数里面有调用了另外一个函数
# 需求:两个函数testA 和 testB ---- 在A里面嵌套调用B
def testB():
print('B函数开始-----')
print('这是B函数')
print('B函数结束-----')
def testA():
print('A函数开始')
# 嵌套调用B
testB()
print('A函数结束')
testA()
打印横线图形
def print_line():
print('-' * 20)
# 函数嵌套调用,实现多条横线
def print_lines(num):
i = 0
while i < num:
print_line()
i += 1
print_lines(5)
任意三个数求平均值
# 任意三个数求平均值
# Python语言当中,做除法运算,不管参与运算的是不是浮点数,只要是除法,结果就是浮点数。
def sum_num(a,b,c):
return a + b + c
def average_num(a, b ,c):
# 先求和,再除以3
sumResult = sum_num(a, b, c)
return sumResult / 3
averageResult = average_num(1, 2, 3)
print(averageResult) # 输出结果为 2.0
9.4 变量的作用域
局部访问
# 定义一个函数,声明一个变量:函数体内部访问,函数体外部访问
def testA():
a = 100
print(a) # 函数体内部访问,能访问到a变量
testA()
print(a) # 报错:a变量是函数内部的变量,函数外部无法访问,这里的a是一个局部变量
访问全局变量
# 声明全局变量:函数体内外都能访问
a = 100
print(a)
def testA():
print(a)
def testB():
print(a)
testA()
testB()
修改全局变量
# 函数体内修改全局变量
a = 100
print(a) # 输出100
def testA():
print(a)
def testB():
global a
a = 200
print(a)
testA() # 输出100
testB() # 输出200
print(a) # 输出200
''' 总结: 1. 如果在函数里面直接把变量a = 200赋值,此时的a不是全局变量的修改,而是相当于在函数内部声明了一个新的局部变量 2. 函数体内部修改全局变量:先global声明a为全局变量,然后再变量重新赋值 '''
多函数执行流程
# 1.声明全局变量 2. 定义两个函数 3.函数1修改全局变量:函数2访问全局变量
glo_num = 0
def test1():
global glo_num
glo_num = 100
def test2():
print(glo_num)
# 疑问:已经再test1中修改了全局变量,为什么这个地方输出结果不是100?因为进行函数调用,没有执行函数体内的代码。
print(glo_num) # 输出结果为0
test2() # 输出的结果为0。还是因为因该全局变量的函数没有执行
test1() # 执行了函数体内的代码
test2() # 输出100
print(glo_num) # 输出100,因为test1函数调用了,修改了全局变量。
9.5 函数返回值(多返回值)
返回值作为参数传递
def test1():
return 50
def test2(num):
print(num)
# 先得到函数1的返回值,再把这个返回值传入到函数2
result = test1()
test2(result)
函数的返回值(多返回值)
# 需求:一个函数有两个返回值1和2
# 一个如果有多个return不能都执行,只执行第一个return:无法做到一个函数多个返回值
# def return_num():
# return 1
# return 2
#
# result = return_num()
# print(result) # 输出结果为1。第二个return不起作用
''' 1. 下面是一个函数多个返回值的正确写法 2. return a,b写法,返回多个数据的时候,默认是元组类型 3. return后面可以连接列表、元组或字典,以返回多个值 '''
def return_num():
return 1,2 # 返回值是元组
# return 后面可以直接写元组、列表、字典、返回多个值.
# return (10,20) # 返回的是元组
# return [100,200] # 返回的是列表
# return {'name':'Python', 'age': 20} # 返回的是字典
result = return_num()
print(result) # return 1,2 输出结果是(1, 2)
9.6 函数的参数的类型
位置参数
def user_info(name,age,gender):
print(f'您的姓名是{name},年龄是{age},性别是{gender}')
user_info('tom',20,'男') # 输出结果为 您的姓名是tom,年龄是20,性别是男
# 注意:传递和定义参数的顺序及个数必须一致
# user_info('tom',20) # 个数定义和传入不一致会报错
# user_info(20,'tom','男') # 顺序也和定义必须是一致的,否则倒是数据无意义
关键字参数
# 函数调用,通过"键=值"形式加以指定
def user_info(name,age,gender):
print(f'您的姓名是{name},年龄是{age},性别是{gender}')
# 1. 调用函数传参
user_info('jack', age=20 , gender='男') # 您的姓名是jack,年龄是20,性别是男
# 2. 关键字参数之间部分先后循序
user_info('jack', gender='男', age=20) # 您的姓名是jack,年龄是20,性别是男
# 3. 位置参数必须写在关键字参数的前面
# user_info(age=20 , gender='男', 'jack') # 报错了。必须关键词放在前面
缺省参数
''' 1.缺省参数(默认参数):为了节省用户的时间成本,提高用户体验,可以把一些需求上带有默认值的这种参数,设置成一个默认值,这样写法的参数,叫做缺省参数(默认参数)。 2. 所有的位置参数必须出现在默认参数的前面 3. 函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值 '''
def user_info(name,age,gender='男'): # gender='男'是缺省参数
print(f'您的姓名是{name},年龄是{age},性别是{gender}')
# 没有为缺省参数传值,表示使用默认值
user_info('tom', 18) # 您的姓名是tom,年龄是18,性别是男
# 为缺省参数传值,使用了gender='女 ',即修改了默认值
user_info('tom', 18, gender='女') # 您的姓名是tom,年龄是18,性别是女
不定长参数之位置参数
''' 1.不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传也可以)的场景。 此时可以用包裹位置参数或者包裹关键字参数,来进行参数传递。 2. 传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组,args是元组类型,这就是包裹位置传递 '''
# 接收所有位置参数,返回一个元组
def user_info(*args):
print(args)
# 包裹位置传递
# 如果是*args接收不定长的位置参数据,可以传数据,也可以不传数据,无论传与不传,将来接收的都是所有位置参数,返回的是都是一个元组
user_info() # ()
user_info('tom') # ('tom',)
user_info('tom', 20) # ('tom', 20)
user_info('tom', 20,'男') # ('tom', 20, '男')
不定长参数之关键字参数
# 收集所有关键字参数,返回一个字典
# 包裹关键字传递
def user_info(**kwargs):
print(kwargs)
user_info()
user_info(name='tom')
user_info(name='tom', age=20)
# 无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程
扩展1:拆包
上面说了不定长参数是组包的过程,那就来说一下拆包的过程
# 1. 拆包元组数据
# def return_num():
# return 100, 200
# result = return_num()
# print(result) # 输出 (100, 200)
# num1, num2 = return_num()
# print(num1) # 输出 100
# print(num2) # 输出 200
# 2. 字典数据拆包:变量存储的数据是key值
# 先准备字典,然后拆包
dict1 = { 'name': 'tom', 'age': 20}
# dict1中有两个键值对,拆包的时候用两个变量接收数据
a , b = dict1
print(a) # 输出name
print(b) # 输出age
# 提取value的值
print(dict1[a]) # 输出tom
print(dict1[b]) # 输出20
print(dict1['name']) # 输出tom
扩展2:交换变量的值
# 方法1:
a= 10
b = 20
c = 0
c = a
a = b
b = c
print(a) # 20
print(b) # 10
# 方法2:
a, b = 1, 2
print(a) # 输出1
print(b) # 输出2
a, b = 1, 2
a, b = b, a
print(a) # 输出2
print(b) # 输出1
9.7 引用作实参
体验引用
# 变量就是存储数据的名字而已,这个名字就可以理解为引用,再python语言中数据其实传递来传递去都是通过变量的形式来传递的
# 简单粗暴的理解,引用就是变量名。引用可以当作实参传入到函数里面
# 1. 不可变类型:int
# 1.1 声明变量保存整型数据,把这个数据赋值到另一个变量:id()检测两个变量的id值(内存的十进制值)
a = 1
b = a
print(b) # 输出1
# 发现a和b的id值相同的
print(id(a)) # 输出 140708418216784
print(id(b)) # 输出 140708418216784
# 修改a的数据测试id值
a = 2
print(b) # 输出1
# 因为修改了a的数据,内存要开辟另外一份内存存储2,id()检测a和b的地址不同
print(id(a)) # 输出 140708418216816
print(id(b)) # 输出 140708418216784
============================================================================
# 2. 可变类型:列表
aa = [10, 20]
bb = aa
print(bb) # [10, 20]
print(id(aa)) # 2266328490632
print(id(bb)) # 2266328490632
# 增加数据
# 列表是可变类型
aa.append(30)
print(aa) # [10, 20, 30]
print(bb) # [10, 20, 30]
print(id(aa)) # 2266328490632 地址值
print(id(bb)) # 2266328490632
引用当作实参
def test(a):
print(a)
print(id(a))
a += a
print(a)
print(id(a))
b = 100
test(b) # 这是不可变类型数据
c = [11, 22]
test(c) # 这是可变类型数据
9.8 可变和不可变类型汇总
小总结:
''' 数据的可变类型:如果对数据进行修改,修改的是原数据,这样的数据是可变类型 数据的不可变类型:如果数据修改的时候改的不是原数据,这样的数据是不可变类型。 可变类型: 列表 字典 集合 不可变类型: 整型 浮点型 字符串 元组 重点: 作用域、函数多返回值、函数的参数 '''
9.9 递归函数和匿名函数(lambda)
递归函数的应用
# 递归函数:1.内部自己调用自己 2.必须有出口
# 递归是一种编程思想,函数是编程的一种体现
# return有两个作用: 1. 返回值 2. 退出当前函数
''' 需求:3以内数字累加和3 + 2 + 1 = 6 6 = 3 + 2以内数字累加和 2以内的累加和 = 2 + 1以内的累加和 1以内的累加和 = 1 # 出口 '''
def sum_numbers(num):
# 2.出口
if num == 1:
return 1
# 1. 当前数字 + 当前数字减一的累加和
return num + sum_numbers(num - 1)
result = sum_numbers(3)
print(result)
# 如果没有出口,报错:超出最大递归深度
匿名函数lambda,来个栗子感受一下
''' 应用场景: 1.lambda的作用就是简化代码 2.如果一个函数有一个返回值,并且只有一句代码,可以使用lambda简化 语法:lambda 参数列表 :表达式 注意: lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用 lambda表达式能接收多个参数但只能返回一个表达式的值 '''
# 需求:函数 返回值100
# 1. 函数
# def fn1():
# return 100
#
# result = fn1()
# print(result)
# 2. lambda 匿名函数,就是不在用def语句定义的函数。如果要声明匿名函数,则要使用lambda关键字
# lambda参数列表:表达式
fn2 = lambda : 100
print(fn2) # lambda内存地址
# 100返回值 调用函数
print(fn2()) # 100
lambda的参数形式
# 1.无参数
# fn1 = lambda: 100
# print(fn1())
# 2. 一个参数
# fn2 = lambda a: a
# print(fn2('hello world'))
# 3. 默认参数/缺省参数
# fn3 = lambda a, b, c = 200 : a + b + c
# print(fn3(10, 20))
# print(fn3(10, 20, 300))
# 4. 可变参数:*args
# fn4 = lambda *args: args
# print(fn4(10))
# print(fn4(10, 20))
# print(fn4(10,20,30,40)) # (10, 20, 30, 40)
# 5. 可变参数: **kwargs
fn5 = lambda **kwargs : kwargs
print(fn5(name = 'Python'))
print(fn5(name = 'Python', age = 30)) # {'name': 'Python', 'age': 30}
带判断的lambda
# lambda应用
# 1. lambda 两个数字比大小,谁大返回值
fn1 = lambda a, b : a if a > b else b
print(fn1(1000, 500)) # 1000
列表数据排序
''' students是一个序列名,指代的就是列表序列,key等于一个 lambda的表达式, 这里面就用到了lambda,sort里面有个参数key,如果列表里面有字典,按照字典某个key进行排序用的。 将来要进行升或降序排序的数据,这里指得是字典,返回值,排序的依据是name key还是age key 里面形参x指代的是所有的字典, '''
students = [
{ 'name':'tom','age':20},
{ 'name':'jock','age':21},
{ 'name':'rose','age':22}
]
# 1. name key对应的值进行降序排序
students.sort(key=lambda x: x['name'])
print(students)
# 2. age key对应的值进行升序排序
students.sort(key=lambda x: x['age'])
print(students)
# 3. age key对应的值进行降序排序
students.sort(key=lambda x: x['age'],reverse=True)
print(students)
lambda小总结
''' 一、 lambda (1)语法 lambda 参数列表: 表达式 (2)lambda的参数形式 无参数: lambda: 表达式 一个参数(多个参数用逗号隔开): lambda 参数:表达式 默认参数: lambda key=value:表达式 不定长位置参数: lambda *args:表达式 不定长关键字参数: lambda **kwargs:表达式 '''
10. 学生管理系统
根据前面所学的知识,把知识综合起来,来做一个简单的学生管理系统。
# 定义功能界面
def info_print():
print('请选择功能------------------')
print('1. 添加学生')
print('2. 删除学生')
print('3. 修改学生')
print('4. 查询学生')
print('5. 显示所有学生')
print('6. 退出系统')
print('-' * 20)
info = []
# 所有的功能函数都是操作学生信息,所有存储所有学生信息应该是一个全局变量,数据类型为列表。
# 添加学生信息的函数
def add_info():
"""添加学生函数""" # 添加函数的说明文档
pass # 当我们还不知道函数体内部要写什么代码的时候,加一个pass作占位,,避免语法出现错误。
# 1.用户输入:学号、姓名、手机号
new_id = input('请输入学号:')
new_name = input('请输入姓名:')
new_tel = input('请输入手机号:')
# 2. 判断是否添加这个学生,如果学生姓名已经存在报错提示;如果姓名不存在则添加数据
global info
# 2.1 不允许姓名重复:判断用户输入的姓名 和 列表里面字典的name对应的值相等,提示
for i in info:
if new_name == i['name']:
print('此用户已经存在')
# return作用:退出当前函数:准备空字典,字典新增数据,列表追加字典
return
# 2.2 如果输入的姓名不存在,添加数据:准备空字典,字典新增数据,列表追加数据
info_dict = { }
# 字典新增数据
info_dict['id'] = new_id
info_dict['name'] = new_name
info_dict['tel'] = new_tel
# print(info_dict)
# 列表追加字典
info.append(info_dict)
print(info)
# 删除学生
def del_info():
"""删除学生"""
del_name = input('请输入要删除学生的姓名:')
global info # 声明全局变量
for i in info: # 遍历列表
if del_name == i['name'] :
# 如果姓名存在,则在列表删除数据
info.remove(i)
break
else: # else的作用:当循环正常结束要执行的代码。就是遍历完列表中的数据,还没有break。
print('该学员不存在!!!')
print(info)
# 修改函数
def modify_info():
"""修改学生信息"""
modify_name = input('请输入要修改的学生的姓名:')
global info
for i in info:
if modify_name == i['name']:
i['tel'] = input('请输入新的手机号:')
break
else:
print('该学生不存在!!!')
# 打印info
print(info)
# 查询学员信息
def search_info():
"""查询学生信息"""
search_name = input('请输入要查询的学生的姓名:')
global info # 声明全局变量
for i in info:
if search_name == i['name'] :
print('查询到的学生信息如下--------------------------')
print(f"学生的学号:{i['id']} , 姓名:{i['name']}, 手机号:{i['tel']}")
break
else:
print('查无此人.....')
# 显示所有学生信息
def print_all():
'''显示所有学生信息'''
print('学号\t姓名\t手机号')
# 打印所有学生的数据
for i in info:
print(f"{i['id']}\t{i['name']}\t{i['tel']}")
while True:
# 1. 显示功能界面
info_print()
# 2. 用户输入功能序号
user_num = int(input('请输入功能序号:'))
# 3. 按照用户输入的功能序号,执行不同的功能(函数)
if user_num == 1:
# print('添加')
add_info()
elif user_num == 2:
# print('删除')
del_info()
elif user_num == 3:
# print('修改')
modify_info()
elif user_num == 4:
# print('查询')
search_info()
elif user_num == 5:
# print('显示所有')
print_all()
elif user_num == 6:
# 退出系统
exit_flag = input('确定要退出吗?yes or no:')
if exit_flag == 'yes':
break # break是最主要的
else:
print('输入的功能序号有误')
# 这个退出系统功能,不用函数去做,1.代码比较简单 2.有一个必要的功能,封装到函数里面可能会出问题
# 退出系统依赖于break,break是当一定条件成立,终止循环用的。终止的是就近的这一层循环,如果把这些代码封装
# 一个函数里面去,这个时候跟while True循环不在一起了,就有可能发生问题的。
11. 高级函数
高阶函数作用: 为了化简代码,增加函数的灵活性
11.1 abs()和round()函数
这两个函数的用法比较简单,来个栗子就会了。but这两个函数不是高阶函数
# abs() 求绝对值用的
print(abs(-10)) # 10
# round() 四舍五入的计算
print(round(1.2)) # 1
print(round(1.6)) # 2
# abs()和round()不是高阶函数
11.2 内置高阶函数(map、reduce、filter)
先来体验一下高阶函数
# 需求: 任意两个数字,先进行数字处理(绝对值或四舍五入)在求和运算
# 1. 写法一
def add_num(a,b):
# 绝对值
return abs(a) + abs(b)
result = add_num(-1.1, 1.0)
print(result) # 2.1
# 2. 写法二
def sum_num(a, b, f):
return f(a) + f(b)
result1 = sum_num(-1,-2,abs)
print(result1) # 3
result2 = sum_num(1.2, 1.4, round)
print(result2) # 2
# 方法二的代码更加简洁,函数灵活性较快
# 函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度较快
''' 高阶函数:把函数作为参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式。 高阶函数其实作用就是为了化简代码,增加函数的灵活性 '''
map()函数
''' map(func, lst),将传入的函数变量func作用到lst变量的每个元素中,并将结果组成新的列表(Python2)/ 迭代器(Python3)返回 '''
# 1. 准备列表数据
list1 = [1, 2, 3, 4, 5]
# 2. 准备2次方计算的函数
def func(x):
return x ** 2
# 3. 调用map
result = map(func, list1)
# 4. 验收成果
# 在打印迭代器的时候,只能返回内存地址,这时要用list()转换数据类型
print(result) # 输出 <map object at 0x00000208211131D0>
print(list(result)) # [1, 4, 9, 16, 25]
reduce函数
''' reduce(func, lst),其中func必须有两个参数. 每次func计算的结果继续和序列的下一个元素作累计计算. 注意: reduce()传入的参数func必须接收2个参数 '''
list1 = [1, 2, 3, 4, 5]
# 1. 导入模块
import functools
# 2.定义功能模块
def func(a, b):
return a + b
# 3. 调用reduce. 作用:功能函数计算的结果和序列的下一个数据作累计计算
result = functools.reduce(func, list1)
print(result) # 输出结果为 15
filter()函数
''' filter(func, lst)函数用于过滤序列,过滤掉不符合条件的元素,返回一个filter对象. 如果要转换为列表,可以使用list()来转换 '''
list1 = [1,2,3,4,5,6,7,8,9,10]
# 1. 定义功能函数:过滤序列中的偶数
def func(x):
return x % 2 == 0
# 2. 调用filter
result = filter(func,list1)
print(result) # <filter object at 0x000002AEA49031D0>
print(list(result)) # [2, 4, 6, 8, 10]