实例如下:
# def my_range(start,stop = None,step=1): # if stop ==None: # stop,start = start,0 # # start = 0 # while start<stop: # yield start # start+=step # # 函数名加括号转换成迭代器 # for i in my_range(0,10,2): # print(i) # for i in range(1,10): # print(i) # 生成器-yield # 定义阶段为普通函数 def build(): print('第一次调用') yield '在yield后面也可以写返回值哦!' print('第二次调用') yield '在yield后面也可以写返回值哦!' # 调用函数不会执行代码,只是转变为生成器 build() # 通过遍历res接收 res = build() # 通过next()函数输出,输出注意调用next()函数和代码行数匹配 ret = res.__next__() # 只有一个打印语句,在调用一次next()报错 # ret = res.__next__() # 打印ret就是获取yield的返回值 print(ret) '''每一次调用next()函数,代码会自动停在yield,并返回后面的值,再次调用会接着上次执行''' res.__next__()
实现1:1还原range()函数功能,用生成器对象
首先回忆一下range函数结构,range(start,stop,step)
实例如下:
# for循环遍历实现1-10 for i in range(1,10): print(i) # 自定义range()函数 # 按照range写参数 def my_range(start,stop = None,step=1): # 如果只输入了一个值,末尾值为起始值互换 if stop == None: stop,start = start,0 # 遍历输出 while start<stop: yield start # 实现步长功能 start+=step # 函数名加括号转换成迭代器 for i in my_range(0,10,2): print(i) '''结果是一样的!'''
用到send()函数,可以避免在yield后多次写入
def doing(name): print(f'{name}走起来!') while True: some_wh = yield print(f'{name}去{some_wh}') # 第一次调用转换成生成器,不执行代码 res = doing('HammerZe') res.__next__() # 用send()传值 res.send('北京') res.send('上海') res.send('广州') # 结果 # HammerZe走起来! # HammerZe去北京 # HammerZe去上海 # HammerZe去广州
经过上面几个例子会发现,yield的作用和return有很大相似的地方,yield与return的异同如下:
相同点:
不同点:
如何创建生成器?
如何获取生成器的元素?有两种方法
for循环 / list遍历
next()函数依次遍历
实例如下:
# 创建一个列表生成式 l = [i for i in range(10)] print(l) # 转换为生成器 l1 = (i for i in range(10)) # 生成器只有通过遍历才会执行,下面为遍历的三种方法 for j in l1: # 或者list(l1) print(j) l2 = (i for i in range(10)) print(l2.__next__()) print(l2.__next__()) print(l2.__next__()) # 结果 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 0 1 2
生成器对象和迭代器对象都是使用一次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) """ 第一次for循环 g = (add(n, i) for i in g) 第二次for循环 g = (add(10, i) for i in (add(10, i) for i in g)) """ # 这里的g取到的是最后一次遍历得到的n传进去计算的,n = 10 res = list(g) print(res) #结果 [20, 21, 22, 23]
大家猜一猜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]
如果有错误的地方请指正,感谢,持续更新中·····