python生成器的实现及原理

105 阅读2分钟
"""
1、迭代
一个接一个读取列表中的值,这个过程叫迭代
"""

# 案例
mylist1=[1,2,3]
for v in mylist1:
    print(v,end=" ")
print()


mylist2=[x*x for x in range(5)]
for v in mylist2:
    print(v,end=" ")

"""
2、生成器
python Generator
解决了资源消耗问题,用一个值,产生一个值,用完就扔。
"""

# 创建一个生成器
data_generator=(x*x for x in range(5))#圆括号打印出来是生成器,中括号打印出来是列表
print(data_generator)#此处打印出来类型是个生成器
for v in data_generator:
    print(v,end="")
print()
print("第二次对生成器进行迭代")
for v in data_generator:
    print(v,end="")
    #这里就什么都没有,因为在第一次迭代的时候就用完了,之后就扔掉了

"""
3、yield
他跟return很像,yied是暂时挂起,之后运行的时候直接从yield这里往下运行
"""
# 案例
# 输出不大于max的所有偶数
def generator_even(max):
    for i in range(0,max+1):
        if i % 2 ==0:
            yield i
'''
yield与return类似
retuen expression   直接退出函数(方法),并返回expression的值
yield也返回值,但是返回的是一个generator,generator当前的值就是yield后面跟的表达式的值
'''
print(generator_even(10))#同样这里产生一个生成器

even_generator=generator_even(10)
for n in even_generator:
    print(n,end=' ')

'''
每一个generator对象都有一个隐含的方法__next__,该方法的返回值就是yield后面表达式的值
当__next__方法调用次数超过迭代次数,会抛出StopIteration异常,所以应该使用try。。。except捕获该异常
'''
print()
even_generator=generator_even(10)
print(even_generator.__next__())#0
print(even_generator.__next__())#2
print(even_generator.__next__())#4
print(even_generator.__next__())#6
print(even_generator.__next__())#8
print(even_generator.__next__())#10
# print(even_generator.__next__())#直接抛出异常
#当调用次数比迭代次数多的时候会直接抛出异常

'''
4、用普通函数模拟生成器函数的效果
'''
#将生成器变成普通的列表
def generator_even(max):
    event=[]
    for i in range(0,max+1):
        if i % 2 ==0:
            event.append(i)
    return event
print()
for v in generator_even(20):
    print(v,end="")