python基础05-函数强化和进阶
强化和进阶
函数强化和进阶
一、组包和拆包
1. 组包
- = 右边有多个数据时, 会自动包装为元组
# 组包,1, 2, 3封装成元组再赋值,多变一
result = 10, 20, 30
print(result, type(result)) # (10, 20, 30) <class 'tuple'>
2. 拆包
- 如果 变量数量 = 容器长度, 容器中的元素会一一对应赋值给变量
- 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
- 除了对元组拆包之外,还可以对列表、字典等拆包
# 拆包,一变多
a, b, c = (10, 20, 30)
print(a) # 10
print(b) # 20
print(c) # 30
3. 应用场景
3.1 交换变量的值
a = 10
b = 20
a, b = b, a # 先自动组包,后自动解包(拆包)
3.2 函数可以同时返回多个数
# 函数可以同时返回多个数
def return_arg():
return 1, 2, 3
# 函数调用
# 变量名 = 函数()
ret = return_arg()
print(ret)
# 返回值直接做拆包
r1, r2, r3 = return_arg()
print(r1, r2, r3)
3.3 字典元素拆包
info_dict = {'name': 'mike', 'age': 34}
# 遍历字典,取出每一个item
for temp in info_dict.items():
print(temp) # 元组:(key, value)
key, value = temp # 元组拆包
print(key, value)
二、引用
1. 引用
引用:是一个变量或值的另一个名字,又称别名
- 赋值本质:给右边的变量或值,起一个别名
可以使用id函数查看变量的引用地址,
引用地址相等,说明指向同一个内存空间
- 每一次运行程序,每次地址都可能不一样
# a 是 10 的引用,10的别名是a,操作a就是操作10
a = 10
print(id(a), id(10)) # 地址id一样,指向同一个内存空间
2. 引用指向改变
# a 是 10 的引用,10的别名是a,操作a就是操作10
a = 10
print(id(a), id(10)) # 地址id一样,指向同一个内存空间
# b 是 a 的引用,b的别名是a,操作a就是操作b
b = a
print(id(b), id(a)) # 地址id一样,指向同一个内存空间
print(a, b) # 10 10
# b 是 20 的引用,20的别名是b,操作b就是操作20
# b已经和上面的a没有关系,现在是20的别名
b = 20
print(b, id(b)) # 和a的地址不一样了,说明b和a没有关系
3. 函数传参是引用传递
- 函数传参是引用传递
# 给函数传参是引用传递
# 带参数函数定义
def func(num):
print('func = ', id(num))
# 给函数传参,变量传参
a = 10
print('func调用前 = ', id(a))
func(a)
print('func调用后 = ', id(a))
运行结果:
func调用前 = 4404906944
func = 4404906944
func调用后 = 4404906944
三、可变类型与不可变类型
1. 可变类型和不可变类型
- 可变类型: 在存储空间中可以直接修改的数据类型
- 列表 list
- 字典 dict
- 集合set
- 不可变类型: 在存储空间中不可以直接修改的数据类型
- 数值类型 int, bool, float
- 字符串 str
- 元组 tuple
"""
可变类型: 列表、字典、集合
不可变类型: 数字类型(int, bool, float)、字符串、元组
可变类型:在地址不变的情况下,可以修改内容
不可变类型: 在地址不变的情况下,不可修改内容
"""
# 验证列表是可变类型
my_list = ['a', 'b']
print('改之前的地址:', id(my_list))
my_list.append('c') # 追加元素
print('改之后的地址:', id(my_list)) # 地址和改之前一样
print(my_list) # ['a', 'b', 'c']
print('=' * 20)
# 验证int是不可变类型
a = 10
print('改之前的地址:', id(a))
a = 20 # a是20的别名,重新指向新的空间,和前面的a没有关系,不是改前面的内容
print('改之后的地址:', id(a)) # 和改之前地址不一样了
print(a) # 20
四、range
1. range的使用
- range() 方法可创建一个整数列表对象,一般用在 for 循环中
- range(开始位置, 结束位置,步长)
- 和切片用法差不多
- range(开始位置, 结束位置,步长)
# 1. 打印:0、1、2、3、4
# for i in range(5): # [0, 5)
for i in range(0, 5): # [0, 5)
print(i)
# 2. 1~100的累加
# 2.1 定义辅助变量
_sum = 0
# 2.2 for 控制循环范围
for i in range(1, 101):
# 2.3 累加
_sum += i
# 2.4 在循环外面打印累加结果
print(_sum)
# 3. 验证步长,打印:0、2、4
for i in range(0, 5, 2): # [0, 5)
print(i)
五、列表推导式
1. 列表推导式
- 列表推导式:快速生成列表元素的表达形式,通过for添加列表元素的简洁写法
- 推导式基本格式: [计算公式 for 循环 if 判断]
- 特点:
- 每循环一次,将计算公式的结果添加到列表中
- 计算公式可以使用遍历出的数据
- for 遍历出的数据 必须满足 if 判断 才会使用计算公式生成元素
# 普通方法:遍历0~4范围的元素,这些元素添加到列表中
# 1. 空列表
new_list = []
# 2. range(5)遍历取数
for i in range(5):
# 2.1 取出来的元素追加到列表
new_list.append(i)
# 3. 循环外面,打印结果
print(new_list)
print('='*30)
# 通过列表推导式,实现上面的效果 [计算公式 for循环体]
# 1. for i in range(5), 取出0,放在i变量中,i追加到列表
# 2. 循环下一步,取出2,放在i变量中,i追加到列表
# 重复,直到退出循环
new_list2 = [i for i in range(5)]
print(new_list2)
print('='*30)
# 0~10之间数,偶数才添加到列表
# 普通方法实现
# 1. 空列表
new_list = []
# 2. range(11)遍历取数
for i in range(11):
# 2.1 取出来的元素是偶数的话,追加到列表
# 2.2 i % 2 == 0, i 对 2求余,结果为0,就是偶数
if i % 2 == 0:
new_list.append(i)
# 3. 循环外面,打印结果
print(new_list)
print('='*30)
# 列表推导式实现
# [i for i in range(11) if i % 2 == 0]
# 1. for i in range(11)取第一个元素
# 2. if i % 2 == 0
# 3. 上面满足条件的i, 条件到列表
new_list2 = [i for i in range(11) if i % 2 == 0]
print(new_list2)
运行结果:
[0, 1, 2, 3, 4]
==============================
[0, 1, 2, 3, 4]
==============================
[0, 2, 4, 6, 8, 10]
==============================
[0, 2, 4, 6, 8, 10]
六、匿名函数
1. 匿名函数
- 匿名函数是简单普通函数的简洁写法
- 定义的函数没有名字,这样的函数叫做匿名函数
匿名函数的语法结构:
lambda [形参1], [形参2], ... : [单行表达式] 或 [函数调用]
示例代码:
# 无参有返回值匿名函数
# a) 匿名函数整体就是函数名字, 函数名字()就是函数调用
ret = (lambda: 1 + 1)()
print(ret)
# b) 给匿名函数起一个函数名字,函数名字()就是调用函数
func = lambda: 1 + 1 # 给匿名函数起一个函数名字叫func
ret = func() # 返回值变量 = 函数名()
print(ret)
print('=' * 30)
# 有参有返回值匿名函数
# a. 直接调用匿名函数
ret = (lambda a, b: a - b)(30, 10)
print(ret)
# b. 先给匿名函数起名,再调用
func = lambda a, b: a - b
ret = func(30, 10)
print(ret)
- 匿名函数中不能使用 while 循环、for 循环,只能编写单行的表达式,或函数调用
- 匿名函数中返回结果不需要使用 return,表达式的运行结果就是返回结果
- 匿名函数中也可以不返回结果。例如:
lambda : print('hello world')
七、递归函数
1. 什么是递归函数
- 如果 一个函数在内部调用其本身,这个函数就是 递归函数。
- 递归函数一般会在特定情况下不再调用函数本身(一定要有出口),否则会导致到达最大递归次数, 程序报错
2. 通过递归函数实现阶乘
阶乘的规律:
1! = 1
2! = 2 × 1 = 2 × 1!
3! = 3 × 2 × 1 = 3 × 2!
4! = 4 × 3 × 2 × 1 = 4 × 3!
...
n! = n × (n-1)!
示例代码:
# 1. 定义函数(参数)
def func(n):
# 2. 如果我是 1 ,直接返回 1
if n == 1:
return 1
# 3. 否则,返回 n * 函数调用自己(n-1)
else:
ret = n * func(n-1)
return ret
# 函数调用
_ret = func(3)
print(_ret)
八、enumerate、del
1. enumerate 的使用
- 通过 for 配合 enumerate 遍历容器同时获取元素索引位置、元素
示例代码:
user_list = [{'name': 'mike', 'age': 34, 'tel': '110'},
{'name': 'yoyo', 'age': 18, 'tel': '120'}]
# 遍历列表,同时把索引位置能打印
# 普通方法实现
# 1. 定义索引位置变量
i = 0
# 2. for遍历列表,打印:索引、元素
for user_dict in user_list:
print(i, user_dict)
# 3. 索引位置+1
i += 1
print('=='*20)
# 通过enumerate方法实现
# enumerate(容器变量):获取到:元素位置,元素
for i, user_dict in enumerate(user_list):
print(i, user_dict)
运行结果:
0 {'name': 'mike', 'age': 34, 'tel': '110'}
1 {'name': 'yoyo', 'age': 18, 'tel': '120'}
========================================
0 {'name': 'mike', 'age': 34, 'tel': '110'}
1 {'name': 'yoyo', 'age': 18, 'tel': '120'}
2. 通过del删除列表元素
- 通过del删除列表元素:
del 列表[索引]
示例代码:
user_list = [{'name': 'mike', 'age': 34, 'tel': '110'},
{'name': 'yoyo', 'age': 18, 'tel': '120'}]
# 通过del删除列表元素 del 列表[索引位置]
print(user_list) # [{'name': 'mike', 'age': 34, 'tel': '110'}, {'name': 'yoyo', 'age': 18, 'tel': '120'}]
# 删除索引位置为0的元素
del user_list[0]
print(user_list) # [{'name': 'yoyo', 'age': 18, 'tel': '120'}]
九、学生名片管理系统
1. 示例代码
# 0. 函数的外面,定义一个全局变量(列表),用于保存用户信息
user_list = [{'name': 'mike', 'age': 34, 'tel': '110'},
{'name': 'yoyo', 'age': 18, 'tel': '120'}]
# 显示菜单函数定义
def show_menu():
print('=' * 20)
print('= 1. 添加学生')
print('= 2. 查询所有学生')
print('= 3. 查询某个学生')
print('= 4. 修改某个学生')
print('= 5. 删除某个学生')
print('= 6. 退出系统')
print('=' * 20)
# 定义新建学生的函数
def add_stu_info():
"""添加学生信息"""
# 1. 输入用户信息:姓名、年龄、电话
_name = input('请输入学生姓名:')
_age = int(input('请输入学生年龄:')) # 年龄应该是整型,所有做了int转换
_tel = input('请输入学生电话:')
# 2. 通过for遍历,取出某个元素后,这个元素就是字典
for user_dict in user_list:
# 2.1 字典[‘name’] == 用户输入的名字,是否相等,相等则跳出循环
if user_dict['name'] == _name:
print('此用户已经存在,请重来')
# 2.2 break跳出循环
break
else:
# 3. for中的else 如果用户不存在列表中,添加用户字典到列表
# 3.1 创建字典
info_dict = {'name': _name, 'age': _age, 'tel': _tel}
# 3.2 追加列表
# user_list是可变类型,没有重新赋值,没有改变原来地址,所以不用global声明
user_list.append(info_dict)
# 显示所有的学生,带序号的
def show_all_stu():
"""显示所有的学生"""
# 1. 遍历前,打印一些提示信息:序号 姓名 年龄 电话
# \t一个tab键的空格
print('序号\t\t姓名\t\t年龄\t\t电话')
# 2. 遍历 for 索引位置,字典 in enumerate(user_list):
for i, user_dict in enumerate(user_list):
# 2.1 打印一个用户的信息 索引位置+1,user_dict[‘name’]……
print('%d\t\t%s\t\t%d\t\t%s' % (i + 1, user_dict['name'], user_dict['age'], user_dict['tel']))
# 显示某个学生
def show_one_stu():
"""显示某个学生"""
# 1. 输入姓名
_name = input('请输入学生姓名:')
# 2. 通过for遍历,取出一个字典user_dict
for user_dict in user_list:
# 2.1 user_dict[‘name’]和输入姓名判断
if user_dict['name'] == _name:
# 2.1.1 如果相等,输出用户信息,退出循环
print('查询到的用户信息如下:')
print('%s\t%d\t%s' % (user_dict['name'], user_dict['age'], user_dict['tel']))
break
# 3. for中的else,循环执行完毕,没有break,说明用户不存在,提示一下
else:
print('查询的用户不存在')
def update_stu_by_name():
"""更新某个学生信息,根据输入的姓名匹配哪个学生"""
# 1. 输入需要修改的用户姓名
update_name = input('输入需要修改的用户姓名:')
# 2. for遍历,带索引的遍历 i, user_dict in user_list
for i, user_dict in enumerate(user_list):
# 2.1 如果user_dict['name']和输入用户名字相等
if user_dict['name'] == update_name:
# 2.1.1 重新输入新的姓名、年龄、电话
_name = input('请输入新的学生姓名:')
_age = int(input('请输入新的学生年龄:'))
_tel = input('请输入新的学生电话:')
# 2.1.2 对user_list[i]['name'] = 新的name
user_list[i]['name'] = _name
user_list[i]['age'] = _age
user_list[i]['tel'] = _tel
# 2.1.3 ……、修改成功打印、break跳出循环
print('修改成功')
break
# 3. for中的else 输入的用户不在列表
else:
print('输入的用户不在列表,请重新输入')
def del_stu_by_name():
"""删除某个学生,根据输入的姓名"""
# 1. 输入用户姓名
_name = input('请输入需要删除的名字:')
# 2. for遍历,带索引的遍历 i, user_dict
for i, user_dict in enumerate(user_list):
# 2.1 如果user_dict['name']和输入用户名字相等
if user_dict['name'] == _name:
# 2.1.1 del 列表[i], 同时break跳出循环
del user_list[i]
print('删除成功')
break
# 3. for中else 输入的用户在列表中,不存在
else:
print('用户不在列表中,无法删除')
# 写一个主程序
def main():
# 1. 死循环
while True:
# 调用菜单
show_menu()
# 2. 用户输入数字
cmd = input("请输入功能数字:")
# 3. 条件选择
if cmd == "1":
# print('添加学生')
add_stu_info()
# print(user_list) # 打印列表,做测试,看数据
elif cmd == "2":
# print('查询所有学生')
show_all_stu()
elif cmd == "3":
# print('查询某个学生')
show_one_stu()
elif cmd == "4":
# print('修改某个学生')
update_stu_by_name()
elif cmd == "5":
# print('删除某个学生')
del_stu_by_name()
elif cmd == "6":
print('退出循环')
break
else:
print('输入有误,请重新输入')
# 调用主程序
main()
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 caijinbo的博客!