生成器:函数内包含有yield的关键字,再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
def chicken():
print('first======>')
yield 1
print('second======>')
yield 2
print('third======>')
yield 3
res=chicken()
#生成器本质就是迭代器,也就是说生成器的玩法,就是迭代器的玩法
# print(res) #得到一个生成器对象
res.__next__() #first======>
res.__next__() #second=====>
res.__next__() #third======>
得到返回值
def chicken():
print('first======>')
yield 1
print('second======>')
yield 2
print('third======>')
yield 3
obj=chicken()
res=obj.__next__()
print(res)
res=obj.__next__()
print(res)
res=obj.__next__() #每次next取的是yield后面的值
print(res)
# first======> #next就能取值,取的是函数的返回值
# 1
# second======> 下一次next基于上一次暂停的位置往下走
# 2
# third======>
# 3
for循环的迭代原理
# for循环原理
def chicken():
print('========>first')
yield 1
print('========>second')
yield 2
print('========>third')
yield 3
obj=chicken()
#1、iter_obj=obj.__iter__(),拿到迭代器
#2、触发iter_obj.__next__(),拿到该方法的返回值,赋值给 item
#3、周而复始,直到函数内不再有yield,即取值完毕
#4、for会检测到StopIteration结束循环
for item in obj:#obj是可迭代对象 obj.__iter__()
print(item)
总结yield:
#1、为我们提供了一种自定义迭代器的方式
#2、可以在函数内用yield的关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器,yield可以像return一样用于返回值,区别return只能返回一次值
而yield 可以返回多次值 yield可以保存函数的执行状态
def my_range():
print('start....')
n=0
while True:
yield n
n+=1
obj=my_range()
print(obj) #生存器的内存地址
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
def my_range(start,stop,step):
n=start
while n<stop:
yield n
n+=step
obj=my_range(3,7,2)
print(obj.__next__())
print(obj.__next__())
for item in my_range(5,10,2)
print(item)
表达式形式yield的应用
def eat(name):
print('%s ready to eat'%name)
food_list=[]
while True:
print('我草靠日')
food=yield food_list#food='骨头
food_list.append(food)#food='泔水',循环一次停在yield
print('%s start to eat%s'%(name,food))
dog1=eat('alex')
#1、 必须初始化一次,让函数停在yield的位置
dog1.__next__()
#2、接下来的事,就是喂狗
#send有两方面的功能
# 1、给yield传值
# 2、同__next__的功能
res1=dog1.send('泔水')#传值 #传多个值要放能存多个值的数据类型里面
print(res1)
res2=dog1.send('骨头')
print(res2)
res3=dog1.send('shit')
print(res3)
三元表达式与列表推导式
三元表达式
条件成立时的返回值 if 条件else不成立的返回值
def max(x,y):
if x> y:
return x
else:
return y
x=10
y=20
res=x if x>y else y
print(res)
三元哪三元呢 中间x>y条件算一元 条件成立的返回值算一元(x) 右边条件成立的返回值算一元(y)
#列表生成式
l=[]
for i in range(1,11)
names=['alex','wxx','lxx']
l=[]
for name in names:
l.append(name+'SB')
print(l)
# 可以简写成
names=[name+'SB' for name in names]
print(names)
列表生成式子
l=[item**2 for item in range(1,11)] print(l)
names=['alex','wxx','egon','lxx','zhangmingyan'] # l=[] # for name in names: # if name != 'egon': # l.append(name + 'SB') # names=l names=[name+'SB' for name in names if name != 'egon'] #列表式可以这么表示 print(names)
语法:[expression for iteml in iterable1 if conditionl]
列表生成式的目的是更方便的造列表
列表生成式只能for if ......for if 不能跟else
错误:l=[item**2 for item in range(1,5) if item>2 else]
字典生成式
s1='hello'
l1=[1,2,3,4,5]
res=zip(s1,l1)
# print(res) #<zip object at 0x00000000021BBEC8>
print(list(res))#[('h', 1), ('e', 2), ('l', 3), ('l', 4), ('o', 5)]
keys=['name','age','sex']
values=['egon',18,'male']
res=zip(keys,values)
print(res)
print(list(res))
print(list(res)) #这里迭代器为什么只可以取值一次
d={}
for k,v in res:
d[k]=v
print(d)
info={'name':'egon','age':18,'sex':'male'}
keys=info.keys()
print(keys)
values=info.values()
print(values)
再把keys和values转回原来的字典
d={k:v for k,v in zip(keys,values)}
print(d)
杂项
t=(i for i in rang(10)) print(t) #花括号字典,中括号列表 小括号不是元祖 #<generator object <genexpr> at 0x00000000020CFCA8>
生成器好处省内存
生成器表达式 g=(i for i in range(10)) # print(g) print(next(g)) print(next(g))
with open('a.txt',encoding='utf-8') as f: #生成器表达式
nums=[len(line) for line in f] # g=(i for i in range(10))
# nums=(len(line) for line in f)
print(max(nums)) #对于生成器表达式来说你造出来那生成器开始没有执行任何代码 直到next才刚刚执行一行代码
print(max(nums))
print(max(nums))
l=['egg%s' %i for i in range(100)]
print(l)
g=('egg%s' %i for i in range(1000000000000))
# print(g)
print(next(g))
print(next(g))
列表生成式相当于直接给了一筐鸡蛋,而生成器表达式,直接给了一只鸡,
只鸡可以无限的下蛋,同一时间只有一个鸡蛋,先拉先吃,而列表要来一个真正的空间存进去
今日作业
今日作业:
1、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?
2、思考题
with open('a.txt',encoding='utf-8') as f:
g=(len(line) for line in f)
print(sum(g))
3、文件shopping.txt内容如下
mac,2000,3
lenovo,3000,10
tesla,1000000,10
chicken,200,1
求总共花了多少钱?
打印出所有的商品信息,格式为
[{'name':'xxx','price':'3333','count':3},....]
求单价大于10000的商品信息,格式同上
4、文件内容如下,标题为:姓名,性别,年纪,薪资
egon male 18 3000
alex male 38 30000
wupeiqi female 28 20000
yuanhao female 28 10000
要求:
从文件中取出每一条记录放入列表中,
列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式
5 根据1得到的列表,取出薪资最高的人的信息
6 根据1得到的列表,取出最年轻的人的信息
7 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
8 根据1得到的列表,过滤掉名字以a开头的人的信息