生成器:函数内包含有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开头的人的信息