欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python 生成器

程序员文章站 2023-11-06 22:45:16
最近重新回忆了一下Python的生成器,下面给大家介绍一下 简单的说,生成器只有在调用的时候在会生成相应的数据,我们来看一个例子 运行结果如下: 其实,这么多行的代码我们可以使用列表生成式一行代码就可以搞定了如下: OK,那看到这,可能有人会问,有什么卵用呢?好处当然是有滴,听我细说,首先列表生成器 ......

最近重新回忆了一下python的生成器,下面给大家介绍一下

简单的说,生成器只有在调用的时候在会生成相应的数据,我们来看一个例子

a = []
for i in range(10):
    a.append(i)
print(a)

运行结果如下:

 Python 生成器

其实,这么多行的代码我们可以使用列表生成式一行代码就可以搞定了如下:

>>> [ i*2 for i in range(10) ]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

ok,那看到这,可能有人会问,有什么卵用呢?
好处当然是有滴,听我细说,首先列表生成器可以省内存
如果我们用一个列表存储很多数据,但我们可能用到的只是前面的一些数据,那么就会耗时耗力,那么对于有规律(后面的元素比前面的大一)的元素,就可以考虑列表生成式

>>> ( i*2 for i in range(10) )
<generator object <genexpr> at 0x0000020dfc10b888>

当我把中括号改为小括号时发现,其实列表生成式返回的是一个内存地址,那么我给它赋值看一下效果

>>> temp = ( i*2 for i in range(10) )
>>> for i in temp:
...     print (i)
...
0
2
4
6
8
10
12
14
16
18
>>>

如果循环的数特别大,我们在看下效果

>>> temp = ( i*2 for i in range(10000000) )
>>> for i in temp:
...     print (i)
...
0
2
4
6
8
...
5134
5136
5138
5140
traceback (most recent call last):
  file "<stdin>", line 2, in <module>
keyboardinterrupt
>>> temp[1000]
traceback (most recent call last):
  file "<stdin>", line 1, in <module>
typeerror: 'generator' object is not subscriptable

还没执行完,被我ctrl+c中止了,中间省略了一些,然后我直接调用temp[1000],报错了,由此看出,生成器只有在调用的时候才生成,不调用的时候没有数据生成,那我怎么取数据呢?
只能调用__next__方法,如下:

>>> temp.__next__()
5142
>>> temp.__next__()
5144
>>> temp.__next__()
5146

朋友们有没有发现一个问题,是接着我暂停的地方开始接着往下取的,那么问题来了,我能不能返回取上一个数据呢?答案是不行的,生成器只能不停的往下next
好的,相信你已经简单了解生成器了,但是这是有规律的表达式,要是没有规律的一些问题,例如,斐波那契数列问题,那可以使用函数实现

def fib(temp):
    n, a, b = 0, 0, 1
    while n < temp:
        print(b)
        a, b = b, a + b
        n = n + 1

fib(10)

此函数正常输出就是斐波那契数列的值,那现在我给他变成生成器

def fib(temp):
    n, a, b = 0, 0, 1
    while n < temp:
        yield b
        a, b = b, a + b
        n = n + 1

print(fib(10))

返回值为<generator object fib at 0x000001de65f1ef10> 这样的内存地址,是不是很眼熟,这就是生成器了