生成器
在编程的过程中,我们常常需要一组有一定长度的有规律的数据,例如列举所有字母,等差等比数列,斐波那契数列等,这时候如果使用人工输入肯定很不现实,虽然可以通过编写一个函数来实现,但数据量一大,在所占空间上就大了,这时候就可以用到python中的yield
语句,写一个生成器。生成器的语法类似于普通的函数,只不过将想要返回的值要通过yield
语句来返回,并且在调用时一个通过for
循环来配合。
def facotrs(n):
for k in range(1,n+1):
if n % k == 0:
yield k
if __name__ == '__main__':
for i in facotrs(100):
print(i)
这是一个求一个数的所有因数的生成器,其中并没通过return
来返回值,而是通过yield
,每次执行到这个语句时,函数就会暂时中断,将k
返回给for
循环的循环变量,然后继续执行,直到函数结束运行,会自动抛出一个StopIteration
异常,告诉for
循环结束。
在面对需要一些复杂且大量的有规律的数据里,可以采用这种办法来实现,优点是生成器不是直接将所需的所有数据都写到内存上,而是按规律一个一个的生成,占用的内存空间小,但缺点也很明显,我们不能直接得到我们想要的数据,需要等待数据的生成,我们才能得到想要的数据。
解析语法
解析语法的作用类似于上述的生成器,更像是生成器的简化版本,同时也弥补了生成器的缺点。例如我们想要生成1~n的n2序列。
# 使用生成器可以这样写
def n2(n):
for i in range(1, n+1):
yield i ** 2
if __name__ == '__main__':
for i in n2(10):
print i
# 利用解析语法可以这样写
n = [ i ** 2 for i in range(1, 11) ]
# 还可以这样
n = [ i for i in n2(10) ]
利用解析语法来生成一些简单的序列相对简单一些,但面对一个规则难以描述的序列,还是生成器或是函数来的方便,但我们也看到了,解析语法结合生成器,就可以解决这个问题,而且也解决了生成器无法随意访问我们想要的数据的问题