python之路-12-生成器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之路-12-生成器相关的知识,希望对你有一定的参考价值。
12.1列表生成式
示例1:
普通做法:
a = [0,1,2,3,4,5,6,7,8,9]
for index,i in enumerate(a):
a[index] *=2
print(a)
列表生成式:
b = [i*2 for i in range(10)]
print(b)
12.2 生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator
12.3列表生成器
b = (i*2 for i in range(10))
总结:列表形式是即使不用元素,也在内存中先生成。生成器保存的是算法,只有在调用时才会生成相应的数据,只记录当前位置,只有一个__next__()方法来获得generator的下一个返回值。2.7里是next()
12.4函数生成器
斐波拉契数列:(Fibonacci)
除第一个和第二个数外,任意一个数都可由前两个数相加得到:1, 1, 2, 3, 5, 8, 13, 21, 34, ...
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b ##相当于t = (b, a + b) # t是一个tuple a = t[0] b = t[1]
n = n + 1
return ‘done‘
fib(10)
fib函数变成generator,只需要把print(b)改为yield b就可以了:
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return ‘done‘
f = fib(5)
print(f.__next__())
print("=============")
print(f.__next__())
for i in f:
print(i)
#!Author:lanhan
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return ‘done‘
print(f.__next__())
print("=============")
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("====start loop======")
#for i in f:
#print(i)
报错的内容是return的内容,异常捕获后就不会报错:
g = fib(6)
while True:
try:
x = next(g)
print(‘g:‘, x)
except StopIteration as e:
print(‘Generator return value:‘, e.value)
break
单线程实现并发的过程
#!Author:lanhan
#单线程实现并发的过程
import time
def consumer(name): ##消费者
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield
print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
c = consumer("lanhan")
c.__next__()
# b1 = "韭菜馅"
# c.send(b1) ##调用yield,并且给yield传值
# c.__next__() ##调用yield
def producer(name): ###生产者
c = consumer(‘A‘)
c2 = consumer(‘B‘)
c.__next__()
c2.__next__()
print("老子开始准备做包子啦!")
for i in range(10):
time.sleep(1)
print("做了1个包子,分两半!")
c.send(i)
c2.send(i)
producer("alex")
以上是关于python之路-12-生成器的主要内容,如果未能解决你的问题,请参考以下文章