二、生成器(可以看做是一种数据类型)
描述:
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator:
列表解析(列表生成式):
1 #生成一个列表[0,1,2,3,4,5,6,7,8,9] 2 #方式一:正常思维 for循环方法生成 3 li=[] 4 for i in range(10): 5 li.append(i) 6 print(li) 7 8 #方式二:列表解析 9 li2=[i for i in range(10)] 10 print(li2) 11 12 li3=[i for i in range(10) if i>5] 13 print(li3)
生成器的两种生成方式:
1 #创建生成器----列表解析方式 2 gen=(i for i in range(10)) 3 #如果想获取迭代器中的元素可以通过next()或__next__()获取 4 print(next(gen)) 5 print(next(gen)) 6 print(gen.__next__()) 7 print(gen.__next__()) 8 print("-----------") 9 #但是一般都不会使用next方法获取生成器中的元素,太恶心!!! 10 #因为生成器也是可迭代对象,所以一般使用for循环获取生成器中的元素 11 for i in gen: 12 print(i) 13 14 #创建生成器----函数方式 15 def func(): 16 yield 0 17 yield 1 18 yield 2 19 yield 3 20 for i in func(): 21 print(i)
具有yield关键字的函数都是生成器,yield可以理解为return,返回后面的值给调用者。不同的是return返回后,函数会释放,而生成器则不会。在直接调用next方法或用for语句进行下一次迭代时,生成器会从yield下一句开始执行,直至遇到下一个yield。
迭代器,可迭代对象,生成器关系: