什么是生成器?
通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator
生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。
生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器.
列表表达式和生成器表达式
# 列表表达式与生成器 list01 = [i + 1 for i in range(3)] generator01 = (i + 1 for i in range(3)) print(list01) # [1, 2, 3] print(generator01) # <generator object <genexpr> at 0x7f3baf1deca8> print(type(list01)) # <class 'list'> print(type(generator01)) # <class 'generator'>
# 可以使用next()来获取元素 # print(next(generator01)) # print(next(generator01)) # print(next(generator01))
# 但是正确做法是使用for循环 for item in generator01: print(item)
yield语句写在__iter__方法中 先调用 __iter__生成生成器 再显式调用__next__
- 调用__iter__方法时,不执行
-
调用迭代器对象的__next__()方法时才执行__iter__函数。
-
每次执行到yield语句时返回数据,暂时离开。
-
待下次调用__next__()方法时继续从离开处继续执行。
class MyRange: def __init__(self, end): self.end = end self.a = 0 def __iter__(self): number = -1 while number < self.end - 1: number += 1 yield number my = MyRange(5) iterator = my.__iter__() print(iterator) # <generator object MyRange.__iter__ at 0x7f1bc6166410> while True: try: item = iterator.__next__() print(item) except StopIteration: break
yield + for循环
含有yield语句的函数调用时,返回值是一个generator object,且调用时不执行;
generator object自带__next__方法;
在for循环中会自动调用__next__方法,挨个地返回yield后面的数据;
所以只需要 含有yield语句的函数 + for循环 就能实现自己想要的迭代效果
def get_event(): list01 = [1, 2, 3, 4] for item in list01: if item % 2 == 0: yield item for item in get_event(): print(item)
内置生成器
1. enumerate(item是生成器对象中元素的索引与元素的值组成的元组)
list01 = [1, 2, 3, 4] for item in enumerate(list01): print(item) # (0, 1) (1, 2) ... for index,item in enumerate(list01): print("索引为%d的元素是%d" % (index, item)) # 索引为0的元素是1 索引为1的元素是2 ...
2. zip
1. 语法:
for item in zip(可迭代对象1, 可迭代对象2….):
语句
2. 作用:将多个可迭代对象中对应的元素组合成一个个元组,生成的元组个数由最小的可迭代对象决定。