生成器
通过列表,可以包含很多很多的元素,但是受到内存的制约,列表的内容一定是有限的。它无法表达无限的内容。比如说,全部的正整数,就不可能被放到一个列表之中去使用。但是,全部的正整数确实是应当可以被用作使用的,因为只需要通过前一个元素,就能够推断出后一个元素了。
因此,在这种情况下,我们有了一种新的东西,就是生成器,也就是generator。生成器无需一下子保存或读取出全部的内容,只需要在需要用到的时候,生成一个,就可以了。
生成器生成式
之前,我们提到了列表推导式,实际上,只要将列表推导式中的[]改为(),就可以创建一个生成器了。如果模仿列表生成式或者列表推导式的名字的话,也许我们应当称之为生成器生成式或者生成器推导式,不过这种说法似乎不是很常见。
注:关于列表推导式,有的时候我称呼其为列表推导式,有的时候我又称呼其为列表生成式,是因为这两种称呼非常通用,使用哪一种都是一样的,所以,就没有为了统一性,而选择只使用其中的一种说法。如果你觉得哪一种说法更好的话,可以自行使用其中的一种。
比如说,之前我们写过这样一个列表生成式,我们将其改为生成器生成式。
1 | python复制代码# 这是之前使用过的一个关于九九乘法表的列表推导式 |
我们可以发现,直接打印一个生成器,是不可以的,因为它是在使用的过程中,才被生成的,因此,我们必须通过next()或者for循环的形式,去使用一个生成器。
1 | python复制代码# 每使用一次next(),就会新生成一个元素 |
创建详细的生成器
虽然通过生成器生成式已经可以创建出生成器,但是,生成式的方式毕竟是一种比较简单的方式,面对一些复杂的需求的话,生成器难以应对。因此,我们可以通过函数定义的形式,得到一个生成器。
这里,我们需要使用一个关键字yield,当函数执行到yield时,会得到yield的内容,并且停止运行,当下一次调用的时候,会从上一次的yield开始继续运行,并执行到下一次yield再次暂停。
比如说,定义一个简单的生成器
1 | python复制代码# 通过函数,定义生成器 |
注意,此时g_num不是一个生成器,g_num是一个函数。当这个函数被调用的时候,我们得到的是一个生成器。我们可以像这样使用。
1 | python复制代码# 生成器的使用 |
总结
虽然通过next()或者for循环两种方式都可以使用生成器,但是一般来说,不会真的手动通过next()调用的。使用for循环来配合生成器使用要更多一些。
本文转载自: 掘金