格式: 列表变量 = [表达式 for 变量 in range(10)]
表达式中需要使用后面的变量
'''
列表推导 式
创建一个具有一百个数字的列表
'''# c_l = []
# for i in range(100):
# c_l.append(i)# 使用列表推导式来完成列表的创建
c_l = [i for i in range(100)]
# c_l = [x for i in range(100)] # 注意,表达的变量使用要和循环中的变量一致print(c_l)
print(len(c_l))# 列表推导 式,带条件的
# 实现列表 中所有的值 都 是3的倍数c_l = [x for x in range(1, 101) if x % 3 == 0]
print(c_l)# 创建一个列表 ,列表 中的每个元素都 是具有两个值 的元组
# c_l = [(x,x) for x in range(10)]
# c_l = [(x,) for x in range(10)]
c_l = [(x, y) for x in range(10) for y in range(3)]
print(c_l)
组包: 将多个值同时赋给一个变量时,解释器会进行自动组包操作
拆包: 将一个容器值(元组),里面的多个数据同时赋值多个变量,解释器会进行拆包操作
注意: 拆包要注意被赋值的变量个数和元组中的值个数相同
'''
组包和拆包
'''# 组包a = 1, 2, 3, 4, 5
print(a)
print(type(a))# 拆包
# 注意:拆包时,容器中的元素个数要和变量个数相同
# a1,a2,a3,a4,a5 = a
# a1,a2,a3,a4,a5 = [1,2,3,4,5]
# a1,a2,a3,a4,a5 = 'abcde'
a1, a2, a3, a4, a5 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
print(a1, a2, a3, a4, a5)
当在函数中,需要返回多个值的情况下,可以在return 后面直接将多个值写出来
解释器在返回时,会将多个值自动进行组包
'''
函数同时返回多个数据
需求:求一个列表数据中的最大值和最小值
'''def get_max_min():cl = [1, 0, 3, 5, 2, 6, 8, 7, 4, 9]# ma = max(cl)# mi = min(cl)cl.sort()ma = cl[len(cl) - 1]mi = cl[0]print(ma, mi)# 解释器在执行代码时,发现return 后成如果有多个值 ,那么就会将这多个值 ,直接组包成一个元组# 然后将这个元组返回。return ma, miret = get_max_min()
# ret = ma, mi -> ret = (ma, mi)print(ret)
print(type(ret))
函数嵌套是指,在一个函数的函数体内,又去调用了另外一个函数
如果函数内调用了另一个函数,那么当前函数会中断执行,跳转到另一个函数位置进行执行,被调用执行结束后,才回到当前函数恢复中断,继续执行
无论函数如何调用: 谁调用函数,被调用函数执行完就返回到谁那去
'''
函数的嵌套调用
嵌套调用是指,在一个被调用的函数体内又调用了另外一个函数
'''# 定义三个函数
def func_a():print('Func A Start...')func_b()print('Func A Stop...')def func_b():print('Func B Start...')func_c()print('Func B Stop...')def func_c():print('Func C Start...')print('Func C Stop...')# 执行函数调用
func_a()

递归调用是一种特殊的嵌套调用
本质就是自己调用自己
'''
函数递归调用
函数在函数体内,又调用 了自己,这种 形式就是递归调用
'''# def func():
# print('Func Start..')
#
# func()
# print('Func Stop..')
#
#
# func()# 求阶乘
# 5! = 1 * 2 *3 * 4 * 5# factorial 阶乘
def factorial(n):if n == 1:return 1return n * factorial(n-1)print(factorial(3))
# print(factorial(5))'''
factorial(5) -> 5 * factorial(4) -> reutrn 5 * 24 -> 120-> 4 * factorial(3) -> return 4 * 6-> 3 * factorial(2) -> reutrn 3 * 2-> 2 * factorial(1) -> return 2 * 1-> return 1
'''s = 1
for i in range(1,6):s *= iprint(s)
全局变量是指定义函数外的变量,不属于任何一个函数,这个变量可以在任何函数中使用.公共
局部变量定义在某个函数中,该变量只在该函数中有效,除该函数外,都不能使用这个变量当全局变量和局部变量同名时,在函数内使用变量,优先使用局部变量
局部变量优先级高于全局变量
'''
全局变量和局部变量
'''# 全局变量
num = 100def func_a():# 定义一个局部变量a_num = 200print(num)print(a_num)def func_b():num = 300print(num)print(num)# 变量查找规则
# LEGB
# Local -> EnClosed -> Global -> Buildins
# 本地 -> 闭包 -> 全局 -> 内建func_a()
func_b()
因为全局变量在使用时,特性是共享,所以可以利用全局变量,实现函数间的数据通信
'''
使用全局变量,共享数据
'''# 全局变量
num = 0c_list = []# 定义一个用来上传数据的函数
def upoad_data():# 如果想修改全局变量,需要声明global numnum = 100print(num)c_list.append(1)# 定义一个用下载数据的函数
def download_data():print(num, c_list)# 测试
download_data()
upoad_data()
download_data()
在定义函数时,函数中的形式参数,被赋值,这个值就是默认值
当在函数调用时,如果给定了值,那么就使用给定值,如果没有给定值,那就使用默认值注意:默认值参数只能出现在参数列表的最右侧
'''
函数的默认值 参数
'''def show(a=0, b=0):print(f'a:{a},b:{b}')print(a + b)show()
show(1)
show(1, 2)# 使用默认值 参数时,需要注意:
# 在默认值 参数的右侧,不能再出现没有默认值 参数def display(a, b=0, c=0):print(a, b, c)display(1)
display(1, 2)
实参
使用位置参数时,因为类型的原因,那么实参的顺序要和形参的顺序完全一致
当没有默认值的情况下,参数的个数和也要一致
# 位置参数
def show(n, s):for c in s:print(f'{n} -- {c}')# show(1,'hello')# show('hello',1)# show(1)

形参
在定义形式参时,每个参数都可以理解成一个key
使用这个key,可以明确的为当前这个参数进行赋值
使用关键字参数,可以忽略参数的顺序问题
# 关键字参数
# 关键参数解决了参数在传递时的顺序问题 ,可以无序传递show(s='hello', n=1)
show(n=1, s='world')
*args 在参数中定义了该形参后,那可以通过 *args 接收多个不确定个数的位置参数
'''
不定长位置参数
'''def my_sum(*args):print(args)s = 0for i in args:s += iprint(s)my_sum(1, 2)
my_sum(1, 2, 3)
my_sum(1, 2, 3, 4)
my_sum(1, 2, 3, 4, 5)
**kwargs 在参数中定义了该形参后,那可以通过 **kwargs 接收多个不确定个数的关键字参数
'''
不定长关键字参数
'''def show(**kwargs):print(kwargs)show(a=1)
show(a=1, b=2)
show(a=1, b=2, c=3)# 定义一个可以接收任何参数的函数
def display(*args, **kwargs):print(f'args:{args}')print(f'kwargs:{kwargs}')display()
display(1, 2, 3)
display(a=1, b=2)
display(1, 2, 3, 4, a=1, b=2)
# display(a=1,b=2,2,3,4)
重点:
记住这种函数定义格式:当定义函数时,如果函数的参数想接收任意类型和个数,那么定义格式如下:def 函数名(*args, **kwargs):函数体内容

如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有**kwargs的话,**kwargs必须是最后的def func(a,b,c,d,e, *args,f=1,g=2,**kwargs):函数体代码
'''
混合参数的写法
'''def func(a, b, c, d, e, *args, f=1, g=2, **kwargs):print(a, b, c, d, e)print(args)print(f, g)print(kwargs)func(1, 2, 3, 4, 5)
func(1, 2, 3, 4, 5, 5, 6, 7, 8, 9)
func(1, 2, 3, 4, 5, 5, 6, 7, 8, 9, f=11, g=22)
func(1, 2, 3, 4, 5, 5, 6, 7, 8, 9, f=11, g=22, h=333, i=444)

'''
可变参数的的二次传递
'''def show(a, *args, **kwargs):print(a)print(args)print(*args)display(*args) # *arsg 手动解包def display(a, b, c, d):print(a, b, c, d)show(1, 2, 3, 4, 5)


引用就是数据在内存中分配的存储空间的地址
id()可以得到数据在内存中的地址
通过引用,可以方便的在函数之间进行数据传递,实现函数间的数据通信

'''
引用的概念
'''# 引用就是数据在内存中存储时的内存编号# 通过 id() 函数可以得到数据在内存中的地址print(id(1))
print(id(1))
print(id(1))a = 1
print(id(1))
print(id(a))b = a
print(id(1))
print(id(a))
print(id(b))
print('*' * 20)a = 2
print(id(1))
print(id(2))
print(id(a))
print(id(b))
为了在程序中使用数据时,效率更高,ptyhon解释会在程序加载后,产生一个缓存区,缓存区中存放是常用的数据
数字: -5 ~ 255
字符串: 长度为小于20的字符串
不可变类型:数字 int字符串 str浮点数 float布尔类型 bool元组 tuple特点: 这些数据都是不可以直接修改的,如果在修改或赋值时,都会开辟一个新空间可变类型:列表 list字典 dict集合 set特点: 这个些数据类型,是可以直接在原对象上进行修改数据,修改完成后,并不影响原对象地址
'''
可变对象的修改
'''c_l = []print(id(c_l))c_l.append(1)
print(id(c_l))

这个程序要理解记住的是逻辑,而不是代码
'''
学生管理系统程序 分析:1. 学生怎么表示2. 学生可能使用 学号 id ,姓名 name, 年龄 age ,可以使用一个字典来表示每一个学生3. 应该有一个容器去保存所有的学生字典 ,可以使用列表实现4. 应该有一个主控函数5. 菜单函数5-1. 选择功能的函数6. 添加学生函数7. 修改学生函数8. 查找学生函数9. 删除学生函数10.显示所有学生的函数11. 因为创建 学生和修改学生,都需要从键 盘输入 数据,那么输入 数据这个功能 就可以提取出一个函数,返回输入的数据12. 添加 一个功能 函数,用来显示每个学生的信息'''# 定义一个学生的列表,用来保存来管理学生students = []# 主控制函数
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':del_id = input('请输入一个要删除的学生ID:')del_stu(del_id)elif select_id == '3':modify_id = input('请输入一个要修改的学生ID:')modify_stu(modify_id)elif select_id == '4':query_id = input('请输入一个要查询的学生ID:')search_stu_with_id(query_id)elif select_id == '5':show_all_info()elif select_id == '6':# break # 因为选择功能没有在循环中,所以不能break# return # 作用同上,函数返回后,返回到调用处,返回到主控函数中的死循环中,所以程序还是不能结束exit(0) # 程序通过 exit() 方法,可以直接结束程序else:print('输入的ID错误 ,请重新输入')# 实现一个输入函数
# 用来从键盘获取学生信息,并返回
def input_stu_info():# 保存输入的学生信息stu_id = input("请输入学号:")stu_name = input('请输入姓名:')stu_age = input('请输入年龄:')# 同时返回多个数据时,会组包成一个元组return stu_id, stu_name, stu_age# 实现 添加函数
def add_stu():# 主体思路 就是向列表 中添加 一个字典# 创建一个学生字典 ,空的stu = {}# 调用 输入函数,获取学生信息stu_info = input_stu_info()# 利用获取的信息为字典添加数据stu['id'] = stu_info[0]stu['name'] = stu_info[1]stu['age'] = stu_info[2]# 将字典加到列表中students.append(stu)print(students)# 实现学生查找的功能
# 返回被找到的学生def search_stu_with_id(stu_id):# 遍历每个学生for stu in students:# 判断学生是否是查找的人if stu['id'] == stu_id:# 找到返回该 学生show_stu_info(stu)return stu# 返回没找到else:print(f'学号为{stu_id}的学生不存在')return None# 实现一个用来显示 单个学生信息的函数
def show_stu_info(stu):print(f"学号:{stu['id']} 姓名:{stu['name']} 年龄:{stu['age']}")# 实现删除学生的函数
def del_stu(del_id):# 找到要删除的学生stu = search_stu_with_id(del_id)# 从列表中删除if stu != None:students.remove(stu)# 实现 修改学生的函数
def modify_stu(modify_id):# 查找学生stu = search_stu_with_id(modify_id)# 如果找到就修改if stu != None:# 先去调用 输入 函数获取数据stu_info = input_stu_info()# 利用获取的信息为字典添加数据stu['id'] = stu_info[0]stu['name'] = stu_info[1]stu['age'] = stu_info[2]# 显示所有学生信息
def show_all_info():# 遍历打印for stu in students:show_stu_info(stu)# 执行主控函数,运行程序
main()