'''
生成器
利用迭代器,我们可以在每次迭代获取数据(通过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
'''
评论
评论功能已经关闭!