一、生成式
1、生成器
-.什么是生成器?
生成的工具。
生成器是一个 "自定义" 的迭代器, 本质上是一个迭代器。
-.如何实现生成器
但凡在函数内部定义了的yield,
调用函数时,函数体代码不会执行,
会返回一个结果,该结果就是一个生成器。
1 # 自定义的迭代器 2 def func(): 3 print('from func') 4 yield 'tank' 5 6 7 res = func() 8 # 当我们通过__next__取值时,才会执行函数体代码。 9 print(res.__next__())
2、yield
每一次yield都会往生成器对象中添加一个值。
- yield只能在函数内部定义
- yield可以保存函数的暂停状态
有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但是不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值
yield与return:
相同点:
返回值的个数都是无限制的。
不同点:
return只能返回一次值,yield可以返回多个值
1 # 自定义的迭代器 2 def func(): 3 print('开始准备下蛋') 4 print('1---火鸡蛋1') 5 yield '火鸡蛋1' 6 print('2---火鸡蛋2') 7 yield '火鸡蛋2' 8 print('3---火鸡蛋3') 9 yield '火鸡蛋3' 10 11 print('取最后一个蛋,查看是否有') 12 13 14 # res是迭代器对象 15 res = func() 16 # 当我们通过__next__取值时,才会执行函数体代码。 17 # next(迭代器对象) 18 print(next(res)) 19 print(next(res)) 20 print(next(res)) 21 22 # 迭代器对象.__next__() 23 print(res.__next__()) 24 print(res.__next__()) 25 print(res.__next__()) 26 print(res.__next__()) # StopIteration报错
自定义range功能,创建一个自定义的生成器
1 # 自定义range功能,创建一个自定义的生成器 2 # (1, 3) # start--> 1 , end---> 5, move=2 3 def my_range(start, end, move=1): # 4 while start < end: 5 yield start 6 start += move 7 8 print(g_range) 9 10 for line in my_range(1, 5, 2): 11 print(line)
输出结果就是:1
3
3、三元表达式
可以将if...else分支变成一行
语法:
条件成立返回左边的值 if 判断条件 else 条件不成立返回右边的值
需求:比较两个值的大小,返回较大值
# 普通判断方法:if...else语法 def max1(num1, num2): if num1 > num2: return num1 else: return num2
1 # 三元表达式: 2 def max2(num1, num2): 3 res = num1 if num1 > num2 else num2 4 print(res) 5 max2(100, 200)
需求:让用户输入用户名,输入的用户名不是以_str结尾,就为其后缀添加_str
1 def func(): 2 name = input('>>>').strip() 3 name = name if name.endswith('_str') else name + '_str' 4 print(name) 5 func()
4、列表生成器
列表生成式:
可以一行实现生成列表。
语法:
list = [取出的每一个值、任意值 for 可迭代对象中取出的每一个值 in 可迭代对象]
for的右边是循环次数,并且可以取出可迭代对象中每一个值
for的左边可以为当前列表添加值
list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象]
list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]
1 # 将list1中的值,依次取出,添加到new_list中 2 list1 = [1, 2, 3, 4] 3 # 普通方式 4 new_list = [] 5 for i in list1: 6 new_list.append(i) 7 print(new_list) 8 9 # 列表生成式 10 new_list = [i for i in list1] 11 print(new_list)
可以赋给任意值
list1 = ['st' for i in range(10)] print(list1)
# 将name中每个人后缀都添加_str name = ['zhansan', 'lisi', 'wangwu'] name_list = [line + '_str' for line in name] print(name_list)
list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]
1 # 将name中的yang过滤掉,其他每个人后缀都添加_str 2 name = ['zhansan', 'lisi', 'wangwu','yang'] 3 new_name = [line + '_str' for line in name if not line == 'yang'] 4 print(new_name)
5、生成器表达式
生成器表达式(生成器生成式):
- 列表生成式: 若数据量小时采用
[line for line in range(1, 6)] ---> [1, 2, 3, 4, 5]
优点:
可以依赖于索引取值,取值方便
缺点:
浪费资源
- 生成器生成式: 若数据量过大时采用
() ---> 返回生成器
(line for line in range(1, 6)) ---> g生成器(1, 2, 3, 4, 5)
优点:
节省资源
缺点:
取值不方便
方法类似于列表生成式,只是[]改成()
1 # 生成一个有1000个值的生成器 2 g = (line for line in range(1, 1000001)) 3 # <generator object <genexpr> at 0x00000203262318E0> 4 print(g) 5 6 # 列表生成式实现 7 list1 = [line for line in range(1, 1000001)] 8 print(list1)
二、面向过程编程
面向过程编程是一门编程思想。
面向过程编程:
核心是 '过程' 二字,过程 指的是一种解决问题的步骤,即先干什么再干什么
基于该编程思想编写程序,就好比在设计一条工厂流水线,一种机械式的思维方式。
优点:
将复杂的问题流程化,进而简单化
缺点:
若修改当前程序设计的某一部分, 会导致其他部分同时需要修改, 扩展性差。
牵一发而动全身,扩展性差。
这里讲一个登录功能的实现
1 # 1、校验密码合法性 2 def get_user_psw(): 3 while True: 4 username = input('输入用户名:').strip() 5 # 效验用户输入是否为字母 6 if username.isalpha(): 7 break 8 else: 9 print('输入不合法') 10 11 while True: 12 password = input('输入密码:').strip() 13 re_password = input('请再次输入密码:').strip() 14 # 效验两次输入密码是否一致 15 if password == re_password: 16 break 17 else: 18 print('两次密码不一样') 19 return username, password 20 21 22 # 2、拼接字符串 23 def cut_user_pwd(username, password): 24 user_pwd_str = f'{username}:{password} ' 25 return user_pwd_str 26 27 28 # 3、保存用户数据,写入文件 29 def save_date(user_pwd_str): 30 # 每个用户名写入一个文件中 31 with open('user_login.txt','a',encoding='utf-8')as f: 32 f.write(user_pwd_str) 33 34 35 # 注册功能 36 def register(): 37 # 1、验证输入用户名与密码的合法性 38 username, password = get_user_psw() 39 # 2、拼接字符串 40 user_pwd_str = cut_user_pwd(username, password) 41 # 3、写入文件 42 save_date(user_pwd_str) 43 44 45 register()
现在需要修改一下功能,需要用户增加输入用户角色,则需要修改源代码
1 # 需要修改一下功能,需要用户增加输入用户角色 2 3 # 用户三种类别 4 level = ['普通用户','管理员用户','超级用户'] 5 6 7 # 1、校验用户、密码合法性 8 def get_user_psw(): 9 while True: 10 username = input('输入用户名:').strip() 11 # 效验用户输入是否为字母 12 if username.isalpha(): 13 break 14 else: 15 print('输入不合法') 16 17 while True: 18 password = input('输入密码:').strip() 19 re_password = input('请再次输入密码:').strip() 20 # 效验两次输入密码是否一致 21 if password == re_password: 22 break 23 else: 24 print('两次密码不一样') 25 26 while True: 27 user_level = input('请输入用户等级:').strip() 28 # 保证用户输入的角色范围[普通用户、管理员用户、超级用户] 29 if user_level in level: 30 break 31 else: 32 print('输入有误') 33 return username, password, user_level 34 35 36 # 2.拼接字符串 37 def cut_user_pwd(username, password, user_level): 38 user_pwd_str = f'{username}:{password}:{user_level} ' 39 return user_pwd_str 40 41 42 # 3.保存用户数据,写入文件中 43 # 每一个用户保存一个文件,以用户的名字当做文件名 44 def save_date(user_pwd_str, username): 45 with open(f'{username}.txt', 'w', encoding='utf-8')as f: 46 f.write(user_pwd_str) 47 48 49 # 注册功能 50 def register(): 51 # 1、验证输入用户名与密码的合法性 52 username, password, user_level = get_user_psw() 53 # 2、拼接字符串 54 user_pwd_str = cut_user_pwd(username, password, user_level) 55 # 3、写入文件 56 save_date(user_pwd_str, username) 57 58 59 register()
三、匿名函数与内置函数
1、匿名函数:
无名字的函数
语法:
lambda :
冒号:左边是参数, 右边是返回值
因为没有名字,而函数的调用需要函数名+(),因而匿名函数需要一次性使用
注意: 匿名函数单独使用毫无意义,它必须配合 “内置函数” 一起使用的才有意义。
1 # 匿名(), return 已经自动添加了 2 # lambda 匿名(): return 1 3 func = lambda : 1 4 print(func()) 5 func = lambda : 1 6 print()
2、内置函数
max求最大值
1 # max求最大值 max(可迭代对象) 2 list1 = [5, 1, 2, 3, 4] 3 4 # max内部会将list1中的通过for取出每一个值,并且进行判断 5 print(max(list1))
1 dict1 = { 2 'a': 800, 3 'b': 10, 4 'c': 2000, 5 'd': 110, 6 'e': 150 7 } 8 # 字符串的比较: ASCII 9 print(max(dict1)) 10 # 11 # # 获取value值最大的 12 print(max(dict1, key=lambda x:dict1[x]))
min求最小值
print(min(dict1, key=lambda x:dict1[x]))
sorted: 默认升序(从小到大) reverse:反转 reverse默认是False
1 dict1 = { 2 'a': 800, 3 'b': 10, 4 'c': 2000, 5 'd': 110, 6 'e': 150 7 } 8 new_dict = sorted(dict1, key=lambda x:dict1[x]) 9 print(new_dict) 10 # reverse 反转 11 new_dict = sorted(dict1, key=lambda x: dict1[x], reverse=True) 12 print(new_dict)