1. 认识生成器
利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator)。生成器是一类特殊的迭代器。
2.如何创建一个生成器:
生成器时一种特殊的迭代器,我们既然知道迭代器的创建方法,那么创建一个生成器也不是一件难事,首先我们先认识第一种生成器的创建的方法:
利用生成器推导式的方法创建一个生成器
# 第一种生成器创建方法 my_list = (x for x in range(10)) print(my_list) print(next(my_list)) print(next(my_list)) print(next(my_list))
执行结果
0 1 2
怎么样这样方式创建一个生成器是不是特别简单呢?需要注意的是列表推导式是[ ]而生成器推导式是(),这一点不要搞错了。
3.利用生成器编写斐波那序数列
我们已经知道了一种生成器的创建方法,接下来我们将通过创建生成器的第二种方法来创建一个斐波那序数列
首先我们先了解下斐波那序数列,斐波那序数列定义了第一个数为0第二个为1,之后的每个数字都为前两个数字之和,简单来说就是类似与 0,1,1,2,3,5.......的数列
# 生成器的第二种创建方法 def dome(num): a = 0 b = 1 # 定义下标值 iter_index = 0 while iter_index < num: item = a a, b = b, a + b iter_index+=1 # 返回自定义的值 ,yield xxx相当于一个暂停jian,下次接着从这里的下一行开始执行,和return有很大的区别 send_values = yield item print(send_values) test = dome(5) values = next(test) print(values) values = next(test) print(values)
values = next(test)
print(values)
values = next(test)
print(values)
运行结果
0 1 1 2
我们可以看到,这种定义方法与定义一个迭代器差不多,比较明显的区别就是yield 替代了return,那么yeild与return有什么区别呢?
首先return是返回并终止函数的执行,如果return有值则返回return后的值,而yeild则是展厅函数的执行,下次执行函数会接着执行yield只有的代码,如果yeild后有值则返回yield后的值
4.生成器的send方法
yeild函数除了能暂停函数的执行外,还能通过send()方法向其发送一个值,接下来我们验证一下:
def dome(num): a = 0 b = 1 # 定义下标值 iter_index = 0 while iter_index < num: item = a a, b = b, a + b iter_index+=1 # 返回自定义的值 ,yield xxx相当于一个暂停jian,下次接着从这里的下一行开始执行,和return有很大的区别 send_values = yield item print(send_values) # 生成器send问题 test = dome(5) print(test) values = test.send(None) print(values) values = test.send(10) print(values) values = test.send(100) print(values)
运行结果
0 10 1 100 1
需要注意的是,第一个send()传的值必须为none,否则会报错。这是为什么呢?这是因为第一次执行时yield返回了result = ?宁没有被执行,如果直接传过去一个非none的值会因为没有人接收而报错。