''' 生成器 利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。 但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。 为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator) 生成器是一类特殊的迭代器。 ''' import sys import time l = [x**2 for x in range(10)] print(l) g = (x**2 for x in range(10)) print(g) ''' >>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> <generator object <genexpr> at 0x0000029D827E6A98> 创建 L 和 G 的区别仅在于最外层的 [ ] 和 ( ) , L 是一个列表,而 G 是一个生成器。 我们可以直接打印出列表L的每一个元素,而对于生成器G,我们可以按照迭代器的使用方法来使用,即可以通过next()函数、for循环、list()等方法使用。 ''' print(next(g)) print(next(g)) ''' >>> 0 >>> 1 ''' for n in g: print(n) ''' yield 在使用生成器实现的方式中,我们将原本在迭代器__next__方法中实现的基本逻辑放到一个函数中来实现,但是将每次迭代返回数值的return换成了yield,此时新定义的函数便不再是函数,而是一个生成器了。 简单来说:只要在def中有yield关键字的 就称为 生成器 ''' def fib(n): current = 0 num1, num2 = 0, 1 while current < n: num = num1 num1, num2 = num2, num1 + num2 current += 1 yield num return 'success...' print('fib:') f = fib(6) for n in f: print(n) ''' 但是用for循环调用generator时,发现拿不到generator的return语句的返回值。 如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中: while True: try: x = next(f) print(f"value:{x}") except StopIteration as e: print(f"生成器返回值:{e.value}") break ''' # 生成器和列表对比 start_time = time.perf_counter() l = [i for i in range(2, 10001, 2)] cost_time = time.perf_counter() - start_time print(f"list创建时间:{cost_time}") print(f"list内存开销:{sys.getsizeof(l)}字节") start_time1 = time.perf_counter() g = (i for i in range(2, 10001, 2)) cost_time1 = time.perf_counter() - start_time1 print(f"生成器创建时间:{cost_time1}") print(f"生成器内存开销:{sys.getsizeof(g)}字节") ''' >>> list创建时间:0.0001462 >>> list内存开销:43040字节 >>> 生成器创建时间:3.6000000000000333e-06 >>> 生成器内存开销:88字节 ''' ''' send唤醒 ''' def gen(): i = 0 while i < 5: temp = yield i print(temp) i += 1 print('send:') A = gen() print(next(A)) print(A.send('haha')) print(next(A)) print(A.send('heihei')) ''' >>> 0 >>> haha >>> 1 >>> None >>> 2 >>> heihei >>> 3 '''
评论
评论功能已经关闭!