python高级编程-生成器

来源:互联网 发布:阿里云服务器ecs配置 编辑:程序博客网 时间:2024/04/29 08:21
生成器(Generators)也是一种迭代器,但是你只能对其迭代一次。这是因为它们并没有把所有的值存在内存中,
而是在运行时生成值。你通过遍历来使用它们,要么用一个“for”循环,要么将它们传递给任意可
以进行迭代的函数和结构。大多数时候生成器是以函数来实现的。然而,它们并不返回一个值,

而是yield(暂且译作“生出”)一个值。

yield是一个关键词,类似return, 不同之处在于,yield返回的是一个生成器

下面是一个计算斐波那契数列的生成器:
'''
#使用列表模式 
def fibon(n):
    a = b = 1
    result = []
    for i in range(n):
        result.append(a)
        a, b = b, a + b
    return result
'''
# generator version
def fibon(n):
    a = b = 1
    for i in range(n):
        yield a
        a = b
        b =  a + b                 
for x in fibon(200000):
    print(x)
    #pass
程序执行顺序:
1、当程序执行for x in fibon(200000):时会调用fibon(n)函数,按照代码顺序执行,
    a = b = 1
    for i in range(n):
        yield a
   执行到yield a时,函数返回
2、返回值赋值给x后,执行print(x),然后再次循环时,程序指针又跳转到yield a,继续执行它下面的代码
        a = b
        b =  a + b
   执行完这2句后,继续它的循环
     for i in range(n):
        yield a
   执行到yield a时,函数又返回
3、这就是一个循环,之后就是重复循环执行
这个例子在输入很大的参数时,用尽所有的资源,我们接下来测试一下
验证时,注释掉print(x),不让程序做任何输出
#使用列表模式,n=20w次,消耗了 14.682s
D:\python -m cProfile fibon.py
         200006 function calls in 14.682 CPU seconds
   Ordered by: standard name
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   14.682   14.682 <string>:1(<module>)
        1    7.819    7.819   14.681   14.681 fibon.py:11(<module>)
        1    6.845    6.845    6.863    6.863 fibon.py:12(fibon)
        1    0.001    0.001   14.682   14.682 {execfile}
   200000    0.016    0.000    0.016    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.002    0.002    0.002    0.002 {range}
#使用生成器模式,n=20w次,消耗了 8.711s
D:\python -m cProfile fibon.py
         200006 function calls in 8.711 CPU seconds
   Ordered by: standard name
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    8.711    8.711 <string>:1(<module>)
        1    0.066    0.066    8.710    8.710 fibon.py:4(<module>)
   200001    8.642    0.000    8.644    0.000 fibon.py:4(fibon)
        1    0.001    0.001    8.711    8.711 {execfile}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.002    0.002    0.002    0.002 {range}
从对比的结果明显看出,使用生成器,使计算占用更少的资源,提高效率。

注意:这个例子会消耗大量资源(CPU、内存),当设置n=100w次时,pc机运行了一会儿后就出现了内存不足的错误。

str对象是一个可迭代对象,而不是一个迭代器。这意味着它支持迭代,但我们不能直接对其进行迭代操作。那我们怎样才能对它实施迭代呢?
是时候学习下另一个内置函数,iter。它将根据一个可迭代对象返回一个迭代器对象。这里是我们如何使用它:
m_str = "hello python"
m_iter = iter(m_str)
next(m_iter)
# Output: 'h'

0 0
原创粉丝点击