生成器
'''
生成器就是迭代器的另一种形式,可以理解为生成器就是一种自定义的迭代器
'''
所以什么是生成器?
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator
# 生成器解决了什么问题?
主要解决了占用内存的问题
如何使用生成器:
"""函数里面只要出现了yield关键字,那么,该函数就有普通的函数变成了生成器,就不在执行该函数了"""
def index():
print('>>>>index')
yield
index()
# 这时候就发现调用函数的时候函数不会执行,所以接下来我们如何执行函数?
def index():
print('>>>>index')
yield
print(res) # <generator object index at 0x000001A377793E60>
res = index()
next(res) # >>>>index
# 这时候我们就可以调用函数内部yield前面的代码了,next一次会执行一次yield前面的函数,再次执行next会从上一次yield的位置处往下继续走,直到遇到第二个yield
print(next(res)) # None
"""如果你打印next的结果,就会返回yield关键字后面的数据"""
# 当yield关键字后面的数据用逗号隔开,有多个的时候,会以元组的形式返回
'''
有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值
'''
自定义range功能
# 如果range函数不能用了,要写一个跟range函数一样的功能?如何来做?
def index(start, stop):
while start < stop:
yield start
start += 1
for i in index(1, 100):
print(i)
# 上面出了没有步长以外,其余功能均已实现,接下来在上面的代码基础上改改,range功能就可以实现了
def index(start, stop=None, step=1):
if not stop:
stop = start
start = 0
while start < stop:
yield start
start += step
for i in index(1, 50,2):
print(i)
yield传参问题
'''
关键字:send
'''
def index(name):
print(f'{name}正在吃东西')
while True:
food = yield
print(f'{name}正在吃{food}')
res = index('kevin')
next(res) # kevin正在吃东西
res.send('大餐') # kevin正在吃大餐
res.send('苹果') # kevin正在吃苹果
'''
针对表达式形式的yield,生成器对象必须事先被初始化一次,让函数挂起在food=yield的位置,等待调用res.send()方法为函数体传值,res.send(None)等同于next(res)。
'''
return和yield的对比
return
1. 函数遇到return直接终止运行
2. return也可以返回多个值
yield
1. 函数遇到yield代码不会立即终止运行,而是"停住"
2. yield也可以返回多个值,以元组的形式返回
3. yield可以把函数变成生成器,而且还支持传参
生成器表达式
res = (i for i in range(10))
print(next(res)) # 0
print(next(res)) # 1
print(next(res)) # 2
print(next(res)) # 3
print(next(res)) # 4
print(next(res)) # 5
print(next(res)) # 6
print(next(res)) # 7
"""生成器表达式如果你不去__next__,是不会给你造出来数据的"""
"""
迭代器、生成器我们都可以把它们看成是"工厂"
你什么时候要数据我们就设么时候给你生产
上述这样做的原因:
节省内存空间
"""
笔试题
# 求和
def add(n, i):
return n + i
# 调用之前是函数 调用之后是生成器
def test():
for i in range(4):
yield i
g = test() # 初始化生成器对象
for n in [1, 10]:
g = (add(n, i) for i in g)
res = list(g)
print(res)
#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
#C. res=[20,21,22,23]
#D. res=[21,22,23,24
常用的内置函数
标签:index,Python,res,生成器,yield,next,print
From: https://www.cnblogs.com/chao0308/p/17458173.html