视频链接:https://www.bilibili.com/video/BV1SE411N7Hi?p=66
理论链接:https://guobaoyuan.gitee.io/new_book/Python/12-1%20%E7%94%9F%E6%88%90%E5%99%A8.html
以下内容仅供个人学习使用,侵删
#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
生成器:生成器的本质是迭代器
生成器的作用:
1.当数据量较大时,建议使用生成器
保留执行位置
生成器的定义:
1.基于函数
2.基于生成器表达式
return和yield的区别
return将值返回,并终止函数
yield将值返回,并记录执行位置
yield能够使循环进行阻塞
yield可以多,next不能多(否则报错)
yield与yield from的区别:
yield返回整个对象
yield from将可迭代对象逐个返回
迭代器和生成器的区别:
对象内存地址
生成器具有send方法
迭代器是内置的,生成器是自己写的
函数中有yield就是生成器
'''
#函数
def func():
return 1#将值返回,并终止函数
print(func())#函数的调用,结果为1
#生成器
# 1.def定义生成器
# 2.func()产生一个生成器
# 3.g=func()把生成器地址赋给g
# 4.g.__next__()触发生成器
# 5.执行生成器内代码
# 6.执行yield,停止
# 7.g.__next__()触发生成器,找到上一个停止的位置,并执行代码到下一个yield位置
def func():
yield 1 #yield是将值返回,并记录执行的位置
yield 2
g=func()#产生一个生成器,得到地址
print(g)
print(g.__next__())#触发生成器执行
print(g.__next__())#继续向下执行
def func():
lst=[]
for i in range(10):
lst.append(i)
yield lst
print(func().__next__())#[1]
print(func().__next__())#[1]
print(func().__next__())#[1],产生了3个生成器,都只取一个
#注意上下的区别
g=func()#只有1个生成器
print(g.__next__())#[0]
print(g.__next__())#[0,1]
print(g.__next__())#[0,1,2]
#--------------------------
def func():
lst=[i for i in range(100)]
yield from lst#将可迭代对象逐个返回
yield lst#将对象整个返回
g=func()
for em in g:
print(em)
'''
怎么区分迭代器和生成器
1.有yield是生成器
2.生成器是自己写的,迭代器是内置的
3.通过对象内存地址查看
4.通过send方法来判断,只有生成器有send方法
'''
######面试题############
ret=[lambda x:x*i for i in range(5)]#[lambda,lambda,lambda,lambda,lambda,]
print(ret)
ret1=[em(2) for em in ret]
print(ret1)#[8, 8, 8, 8, 8]
#------等同于---------
ret=[]
for i in range(5):
ret.append(lambda x:x*i)#此处lambda没有被调用
#出循环后,i=4
# #下面解释为什么在第一个for循环后,i=4
# for i in range(5):
# def func():#执行for循环时,func没有被调用,保存的是代码
# print(i)
# func()#此处执行结果,打印4
ret1=[]
for em in ret:#2*4=8
ret1.append(em(2))#[8, 8, 8, 8, 8]
#-----------------------------------
#注意与上面的区别
#生成器有惰性机制
ret=(lambda x:x*i for i in range(5))#此处仅产生了5个生成器地址
ret1=[em(2) for em in ret]#ret1中for循环走一遍,ret中的for循环才执行一遍
print(ret1)#[0, 2, 4, 6, 8]