哪有什么岁月静好,不过是有人替你负重前行!

生成器

生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

 1 L = [x * x for x in range(10)]
 2 print(L)
 3 #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
 4 g = (x * x for x in range(10))
 5 
 6 #g=<generator object <genexpr> at 0x1022ef630>
 7 
 8 print(next(g)) #python3.0以后的版本需要print,python3.0之前的版本只需要next(g)就可以了
 9 print(next(g))
10 print(next(g))
11 print(next(g))
12 #0
13 #1
14 #4
15 #9

创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

我们讲过,generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

当然,上面这种不断调用next(g)实在是太变态了,正确的方法是使用for循环,因为generator也是可迭代对象:

g = (x * x for x in range(10))
for n in g:
...     print(n)
...
输出结果为:
0
1
4
9
16
25
36
49
64
81

 

posted @ 2021-09-14 11:41  longfei825  阅读(42)  评论(0编辑  收藏  举报