生成器以及面向过程编程
一、什么是生成器?
生成器就是生成的工具
函数内部包含有yield的关键字,调用函数时,函数体代码不会执行,会返回一个结果,该结果就是一个生成器。
注意:
yield只能在函数内部定义,每一个yield只能往生成器中添加一个值
yield可以保持函数暂存的状态
#自定义迭代器,之前我们用的迭代器都是python给我们的,现在我们自定一个迭代器
def func():
print('from func1')
yield 1
print('from func2')
yield 2
print('from func3')
yield 3
print('结束啦')
res = func()#此时调用函数会返回一个结果,该结果就是一个生成器,本质是迭代器
>>><generator object func at 0x000001EB8258C948>
既然是迭代器那我们就可以使用.___iter___()方法
print(res.__next__())#每遇到一个yield就返回一次,不同于return可以多次返回
print(res.__next__())
print(res.__next__())
# next(迭代器对象)简便方法书写(***)
# print(next(res))
# print(next(res))
# print(next(res))
>>>from func1
1
from func2
2
from func3
3
#自定义一个range生成器
def my_range(start, end, move = 2):
while start < end:
yield start#保存每一次start
start += move
print(my_range(1, 7))#此时得到的是一个生成器
#>>><generator object my_range at 0x0000023A16B5FB48>
res = my_range(1, 7)#此时我的res是一个生成器,本质上就是一个迭代器,那么我们就可以使用for循环
for line in my_range(1, 7):
print(line)
>>>
<generator object my_range at 0x00000200C9F4EB48>
1
3
5
相同点:
返回值的个数都是无限制的。
不同点:
return只能返回一次值,yield可以返回多个值
二、面向过程编程
'''
思想!!!
面向过程编程是一门编程思想。
面向 过程 编程:
核心是 '过程' 二字,过程 指的是一种解决问题的步骤,即先干什么再干什么
基于该编程思想编写程序,就好比在设计一条工厂流水线,一种机械式的思维方式。
优点:
将复杂的问题流程化,进而简单化
缺点:
若修改当前程序设计的某一部分, 会导致其他部分同时需要修改, 扩展性差。
牵一发而动全身,扩展性差。
'''
# #1、先让用户输入用户名密码,校验合法性
# def get_user_pwd():
# while True:
# username = input('请输入您的姓名:').strip()
# #判断用户输入的用户名是否是中午或英文
# if username.isalpha():
# break
# else:
# print('您输入的姓名格式有误')
#
# while True:
# password = input('请输入您的密码:').strip()
# re_password = input('请再次输入您的密码').strip()
# if password == re_password:
# break
# else:
# print('两次密码不一致')
#
# return username, password
#
# #2、拼接用户字符串
# def cut_user_pwd(user,pwd):
# user_pwd_str = f'{user}:{pwd}
'
# return user_pwd_str
#
# #3、保存用户数据,写入文件中
# def save_data(user_pwd_str):
# with open('user.txt', 'w', encoding='utf-8') as f:
# f.write('cut_user_pwd')
#
# #注册功能demo
# def register():
# # 1、先让用户输入用户名密码,校验合法性
# user, pwd = get_user_pwd()
# #2、拼接字符串
# user_pwd_str = cut_user_pwd(user, pwd)
# #3、保存数据
# save_data(user_pwd_str)
#
# register()
list1 = ['普通用户','管理员用户','超级用户']
#1、先让用户输入用户名和密码,校验合法性
def get_user_pwd():
while True:
username = input('请输入您的姓名:').strip()
#判断用户输入是否是中午和英文
if username.isalpha():
break
else:
print('用户名不合法')
while True:
password = input('请输入您的密码:').strip()
re_password = input('请再次输入您的密码:').strip()
if password == re_password:
break
else:
print('两次输入不一致')
# 作业: 保证用户输入的角色范围 [普通用户、管理员用户、超级用户]
# user_role = input('请输入您的角色').strip()
user_role = input('请输入您的角色').strip()
return username, password, user_role
#2、拼接用户字符串
def cut_user_pwd(user,pwd,user_role):
user_pwd_str = f'{user}:{pwd}:{user_role}
'
return user_pwd_str, user # 这里为什么要返回user?
#3、保存用户数据,写入文件
#每一个用户当一个用户名,以用户的名字当做文件
def save_data(user_pwd_str, user_name):
with open(f'{user_name}.txt', 'w', encoding='utf-8')as f:#这是什么原因报错?
f.write(user_pwd_str)
#注册功能
def register():
# 1.设计先让用户输入用户名和密码,校验合法性,得到合法的用户名与密码
user, pwd, user_role = get_user_pwd()
# 2.设计字符串的拼接, 得到拼接好的字符串
user_pwd_str, user_name = cut_user_pwd(user, pwd, user_role)
# 3.开始写入文件
save_data(user_pwd_str, user_name)
register()
三、三元表达式
'''
三元表达式:
可以将if...else...分支变成一行。
语法:
条件成立返回左边的值 if 判断条件 else 条件不成立返回右边的值
'''
#三元表达式比较大小
a = 10
b = 20
res = a if a > b else b
print(res)
# 需求: 让用户输入用户名,输入的用户如果不是yafeng,为其后缀添加_DSB
username = input('请输入你的姓名:')
new_name = username if username == 'yafeng' else username + '_DSB'
print(new_name)
>>>
20
请输入你的姓名:xiaoming
xiaoming_DSB
四、列表生成式
'''
列表生成式:
可以一行实现生成列表。
语法:
list = [取出的每一个值、任意值 for 可迭代对象中取出的每一个值 in 可迭代对象]
list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象]
list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]
'''
# 将list1中的值,依次取出,添加到new_list中
#普通方式
list1 = [1, 2, 3, 4]
new_list = []
for i in list1:
new_list.append(i)
print(new_list)
#列表生成式
new_list = [i for i in list1]# 值 for 可代表可迭代对象每一次取出的值的变量 in 可迭代对象
print(new_list)
五、生成器生成式
'''
生成器表达式(生成器生成式):
- 列表生成式: 若数据量小时采用
[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)
优点:
节省资源
缺点:
取值不方便
'''
g = (line for line in range(1, 101))#此时g是一个生成器
print(g)#<generator object <genexpr> at 0x000001623EADFB48>
列表生成式是[]
生成器生成式是()
列表生成式print可直接打印出列表
生成器生成器print其实是一个生成器,即迭代器
六、匿名函数
'''
匿名函数:
无名字的函数
# :左边是参数, 右边是返回值
lambda :
PS: 原因,因为没有名字,函数的调用 函数名 + ()
匿名函数需要一次性使用。
注意: 匿名函数单独使用毫无意义,它必须配合 “内置函数” 一起使用的才有意义。
有名函数:
有名字的函数
'''
#有名函数
def func():
pass
func()#可直接用函数名加括号调用
#匿名函数lambda
func = lambda : 1#临时赋值一个func函数名,因为它本身没有名字,用完即消失
print(func())
七、内置函数
'''
内置函数:
range()
print()
len()
# python内部提供的内置方法
max, min, sorted, map, filter
sorted: 对可迭代对象进行排序
'''
# max求最大值 max(可迭代对象)
# max内部会将list1中的通过for取出每一个值,并且进行判断
list = [1, 2, 3, 4, 5]
print(max(list))
>>>5
dict1 = {
'tank': 1000,
'egon': 500,
'sean': 200,
'jason': 500
}
# 获取dict1中薪资最大的人的名字
# 字符串的比较: ASCII
print(max(dict1, key=lambda x: dict1[x]))
>>>tank
# 获取dict1中薪资最小的人的名字
print(min(dict1, key=lambda x: dict1[x]))
>>>sean
# sorted: 默认升序(从小到大) reverse:反转 reverse默认是False
list1 = [10, 2, 3, 4, 5]
print(sorted(list1))
>>>[2, 3, 4, 5, 10]
# # reverse=True--> 降序
print(sorted(list1, reverse=True))
>>>[10, 5, 4, 3, 2]
dict1 = {
'tank': 100,
'egon': 500,
'sean': 200,
'jason': 50
}
# new_list = ['egon', 'sean', 'tank', 'jason']
new_list = sorted(dict1, key=lambda x: dict1[x], reverse=True)
print(new_list)
>>>['egon', 'sean', 'tank', 'jason']