python中的生成器(generator)总结

1.实现generator的两种方式

python中的generator保存的是算法,真正需要计算出值的时候才会去往下计算出值。它是一种惰性计算(lazy evaluation)。

要创建一个generator有两种方式。

第一种方法:把一个列表生成式的[]改成(),就创建了一个generator:

>>> L=[x * x for x in range(10)]
>>> L
[0,1,4,9,16,25,36,49,64,81]
>>> g = (x * x for x in range(10))#注意把[]改成()后,不是生成一个tuple,而是生成一个generator
>>> g
<generator object <genexpr> at 0x1022ef630>

第二种方式:在函数中使用yield关键字,函数就变成了一个generator。

函数里有了yield后,执行到yield就会停住,当需要再往下算时才会再往下算。所以生成器函数即使是有无限循环也没关系,它需要算到多少就会算多少,不需要就不往下算。

def fib():
    a,b = 0,1
    while True:
        yield a
        a, b = b, a + b

f = fib()
print (f, next(f),next(f),next(f))
#<generator object fib at 0x7f89769d1fa0> 0 1 1

如上例,第一次输出f,它就是一个generator,之后每次next,它就执行到yield a。

当然其实平常很少用到next(),我们直接用for循环就可以遍历一个generator,其实for循环的内部实现就是不停调用next()。

生成器可以避免不必要的计算,带来性能上的提升;而且会节约空间,可以实现无限循环(无穷大的)的数据结构。

2.可迭代对象(Iterable)和迭代器(Iterator)的概念

可以直接作用于for循环的对象统称为可迭代对象:Iterable。

包括集合数据类型(list、tuple、dict、set、str等)和生成器(generator)。

可以使用isinstance()判断一个对象是否是Iterable对象。

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
>>>from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)),Iterable)
True
>>> isinstance(100,Iterable)
False

迭代器:Iterator。

它表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

生成器(generator)都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]),Iterator)
True
>>> isinstance( iter('abc'),Iterator)
True

Python的for循环本质上就是通过不断调用next()函数实现的,例如:

for x in [1,2,3,4,5]:
    pass

实际上完全等价于:

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
#首先获得Iterator对象:
it= iter([1,2,3,4,5])#循环:
while True:
    try:
        #获得下一个值:
        x = next(it)
    except StopIteration:
        #遇到StopIteration就退出循环
        break

3.itertools模块

python的内置模块itertools提供了用于操作迭代对象的函数,非常方便实用。举一个例子:

islice(iterable, [start, ] stop [, step]):

创建一个迭代器,生成项的方式类似于切片返回值: iterable[start : stop : step],将跳过前start个项,迭代在stop所指定的位置停止,step指定用于跳过项的步幅。与切片不同,负值不会用于任何start,stop和step,如果省略了start,迭代将从0开始,如果省略了step,步幅将采用1.

from itertools import islice

def fib():
    a, b = 0,1
    while True:
        yield a
        a, b = b,a + b

f = fib()
print (list(islice(f,10)))

#[0,1,1,2,3,5,8,13,21,34]

结尾给大家推荐一个非常好的学习教程,希望对你学习Python有帮助!

Python基础入门教程推荐icon-default.png?t=LA46https://www.bilibili.com/video/BV1LL4y1h7ny?share_source=copy_web

Python爬虫案例教程推荐icon-default.png?t=LA46https://www.bilibili.com/video/BV1QZ4y1N7YA?share_source=copy_web

 

  • 15
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值