python基础入门---生成器

生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。

而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,

那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?

这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
       #print(b)
        yield b  #只要有它在,这里就不是函数了,是一个生成器了。 把fib函数变成generator了。
        a, b = b, a + b  # 相当于 t = (b, a + b)  t是一个tuple   a = t[0]  b = t[1]
        n = n + 1
    return '---yyyy----'
        
 f=fib(10) print(f.__next__()) print(f.__next__()) print(f.__next__()) print(f.__next__()) print("------") for i in f:     print(i)

我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

同样的,把函数改成generator后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代:

 for n in fib(6):
     print(n)
 
 
 
 
 
 
  
但是用for循环调用generator时,发现拿不到generator的return语句的返回值。
如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIterationvalue中:
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
       #print(b)
        yield b  #只要有它在,这里就不是函数了,是一个生成器了。 把fib函数变成generator了。
        a, b = b, a + b  # 相当于 t = (b, a + b)  t是一个tuple   a = t[0]  b = t[1]
        n = n + 1
    return '---yyyy----'

g= fib(6)
while True:
    try:
        x = next(g)
        print("g:",x)
    except StopIteration as e:
        print("Generator return value:",e.value)
        break
 
 
 
扫描二维码关注公众号,回复: 10251546 查看本文章






 
 

最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。

 
 

而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行data = fib(print(data)


print(data.__next__()) print(data.__next__()) print("干点别的事") print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) #输出 <generator object fib at 0x101be02b0> 1
1
干点别的事
2
3
5
8
13

猜你喜欢

转载自www.cnblogs.com/qjhh/p/12587499.html