人人都能看懂的「迭代器、生成器」入门指南( 二 )


创建生成器的方法很简单,只需要将列表推导式中的[]换成就行了,例如
mygenerator = (x*x for x in range(3)) for i in mygenerator:...print(i)014但是我们不能多次执行for i in mygenerator,因为生成器只能使用一次!
另外要强调的是「生成器也是特殊的迭代器」因此它拥有上面几节介绍的迭代器的相关性质!
2.2 yield
最后来说说让任何多人头疼的 yield 语法 。
用通俗的话去说,可以将它看成return,只不过它返回的是一个生成器,记住在初学时不需要想明白这个yield到底是什么,但务必了解它的运行机制!
下面让我们看一段代码
def f123:...print("第一次运行")...yield 1...print("第二次运行")...yield 2...print("第三次运行")...yield 3 gen = f123 gengenerator object f123 at 0x7fcd301274a0可以看到,如果一个函数,使用yield关键词返回值,那么它就是一个生成器函数(f123) 。
与普通函数不同,生成器函数被调用后,其函数体内的代码并不会立即执行(执行gen = f123后没有打印出任何值),而是返回一个生成器(gen)!
上面说到,生成器也是迭代器,且yield就当作return看,所以下面的代码运行结果是可以轻松猜到的
for item in gen:...print(item)第一次运行1第二次运行2第三次运行3重点来了,如果使用 next(gen) 会发生什么?
next(gen)第一次运行1 next(gen)第二次运行2 next(gen)第三次运行3 next(gen)Traceback (most recent call last)ipython-input-17-6e72e47198db in module---- 1 next(gen)StopIteration: 我们可以看到,每次调用next(gen)都只运行到yield位置停止,下一次运行时从上一次结束的位置开始! 并且该生成器的长度取决于函数中yield出现的次数 。
在这里想多插一句,虽然我们将yield当成return看,上面的打印出来的1、2、3我们应该将它称为生成值,而不是返回值,这不是某个函数返回的值,而是生成器生成的!希望大家可以再去体会一下!
好了,如果你看明白了上面这个最简单的 yield 函数示例,我们接着看下一个例子,生成器也可以接受参数 。
在生成器函数中,如果将 yield 放在左边,就可以使用 send 方法传递参数,注意看下面的案例
def simple_coro2(a):print('- Started: a =', a)b = yield aprint('- Received: b =', b)c = yield a + bprint('- Received: c =', c)gen = simple_gen(14)这里我们依旧是定义了一个生成器函数,思考一下执行next(gen)会发生什么
【人人都能看懂的「迭代器、生成器」入门指南】next(gen)- Started: a = 1414上一个例子说到「每次调用next(gen)都只运行到yield位置停止,下一次运行时从上一次结束的位置开始!」
所以现在并没有执行b = yield a,仅是将左边yield a执行,生成了a并打印 - Started: a = 14 消息,然后产出 a 的值,并且暂停,等待为 b 赋值 。之后可以使用gen.send(28)来传递28给b
gen.send(28)- Received: b = 2842依旧是执行到yield a + b结束,并等待等待为 c 赋值 。现在如果我们给c赋值会发生什么?
gen.send(99)- Received: c = 99Traceback (most recent call last)ipython-input-51-77455e0ba24f in module---- 1 gen.send(99)StopIteration:可以看到在把数字 99 发给暂停的生成器;计算 yield 表达式,得到 99,然后把 那个数绑定给 c 。打印 - Received: c = 99 消息然后终止,导致生成器对象抛出 StopIteration 异常 。
现在可以通过下面一张流程图来加深上面案例的过程,可能不太适应这种 = 右边的代码在赋值之前执行并暂停的形式,但是必须要理解,这是掌握 yield 最关键的知识!
好了,以上就是有关 Python 中迭代器、生成器的简单入门讲解!


以上关于本文的内容,仅作参考!温馨提示:如遇专业性较强的问题(如:疾病、健康、理财等),还请咨询专业人士给予相关指导!

「辽宁龙网」www.liaoninglong.com小编还为您精选了以下内容,希望对您有所帮助: