Python语言之迭代器与生成器详解
小标 2018-12-20 来源 : 阅读 1228 评论 0

摘要:本文主要向大家介绍了Python语言之迭代器与生成器详解,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

本文主要向大家介绍了Python语言之迭代器与生成器详解,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。python提倡使用生成器,生成器也是迭代器的一种。python可迭代对象和迭代器要点:迭代即遍历,那么可迭代对象顾名思义就是可以遍历的数据类型或结构,表现在python中就是支持for循环遍历的对象。python中有Iterable类代表可迭代对象,所有的可迭代对象都属于这个类;Iterator类表示迭代器,所有的迭代器对象都属于这个类;可迭代对象为什么可迭代?因为可迭代对象的内部实现了迭代器这种行为模式,其在python中的表现就是__iter__魔法方法。也就是说所有python内建的数据结构如str、list等预先已在定义结构时使用__iter__方法实现了迭代器.可迭代对象和迭代器的原理根据上面的要点我们自定义可迭代对象:from collections import Iterableclass MyIterable(object):

    def __iter__(self):
        passmy_iter = MyIteradle()

print(isinstance(my_iter,Iterable))# 结果:True说明python解释器是通过判断一个对象是否有__iter__魔法方法来确定是否是可迭代对象。现在我们尝试用for...in...遍历一下我们定义的可迭代对象:my_iter = MyIter()for i in my_iter:
    print(i)

结果:
TypeError: iter() returned non-iterator of type 'NoneType'报错了,为什么?我们需要知道for...in...干了什么事:python解释器遇到for...in关键字时,第一步找到in后面的my_iter对象,寻找内部的__iter__魔法方法,如果有就执行这个方法,该方法会生成一个迭代器;第二步从迭代器中取出一个值,并将这个值赋值给i.那么清楚了,上述我们虽然有了__iter__魔法方法,但是它并不会返回一个迭代器,从迭代器中取值这个动作也没有。那么我们需要实现一个迭代器。为了便于理解,我们把可迭代对象想象成一个容器,里面存放了我们的数据;迭代器想象成以可迭代对象为原型,在上面加装了一种方法可以顺序访问一个可迭代对象中各个元素,for循环干的事就是获取这个迭代器并从迭代器中取数据。记住:可迭代对象和它的迭代器是两个不同的对象。如此我们可知,既然迭代器的原型是可迭代对象,那么自然也要有__iter__魔法方法了,可是这个方法要求返回一个迭代器,那么不无限循环了吗?我们可以让其返回它自己就可以了。另外要加一个方法实现从迭代器中取数据啊,python解释器规定这个方法为_next_.from collections import Iterable, Iteratorclass MyIterator(object):

    def __iter__(self):
        return self    def __next__(self):
        return 0my_iterator = MyIterator()
print(isinstance(my_iterator, Iterator))for i in my_iterator:
    print(i)# 结果:True没有报错,由此我们可知在python中实现了__iter__和__next__方法的对象就是迭代器。完成了吗?并没有,看迭代器定义:提供一种方法顺序访问一个聚合对象中各个元素;顺序访问,由此有:class MyIterator(object):

    def __init__(self, mylist):
        self.mylist = mylist        # current用来记录当前访问到的位置
        self.current = 0

    def __next__(self):
        if self.current < len(self.mylist):
            item = self.mylist[self.current]
            self.current += 1
            return item        else:            raise StopIteration    def __iter__(self):
        return self显性获取和使用迭代器使用for...in...关键字,python解释器把获取迭代器和从迭代器中取值的过程全部自动完成了,如果我想手动一步步实现这个过程怎么办呢?python提供了显性的方法iter()和next().# 两种方法可以获取一个对象的迭代器l = [0,1,2]print(l.__iter__())print(iter(l))# 结果:手动遍历# 使用next方法取值l = [0,1,2]
ter = iter(l)
print(ter)while True:    try:
        print(next(ter))    except StopIteration:        break生成器生成器是一类特殊的迭代器,什么意思?假如我们想自定义一个迭代器,那么我们需要手动实现__iter__和__next__方法,这显然太过麻烦,于是python为我们提供了一个简单快速的方法。def my_iterator(mylist):
    current = 0
    while current < len(mylist):
        res = mylist[current]
        current += 1
        yield res    return '遍历完成'l = [0,1,2,3]
F = my_iterator(l)for i in F:
    print(i)可以看到,我们把__next__方法中的逻辑抽出来,使用yield返回一个结果,这种简便的结构就是生成器了,本质上是一种快速获得迭代器的方法。此时my_iterator的return值通过for循环是获取不到的,而是需要StopIteration捕捉。l = [0,1,2,3]
F = my_iterator(l)while True:    try:
        next(F)    except StopIteration as e:
        print("生成器返回值:%s"%e.value)        break此时的next()函数可以唤醒生成器,另外我们可以使用send()方法来唤醒生成器,同时传递一个值到生成器中。def my_iterator(mylist):
    current = 0
    while current < len(mylist):
        res = mylist[current]
        current += 1
        i = yield res
        print(i)    return '遍历完成'l = [0,1,2,3]
F = my_iterator(l)while True:    try:
        f.send('aaaa')    except StopIteration as e:
        print("生成器返回值:%s"%e.value)        break生成器生成式在逻辑足够简单的时候,一个更快捷的创建生成器的方法:f = (i for i in range(10)) #   此时f表示的不是元组而是生成器

本文由职坐标整理并发布,希望对同学们学习Python有所帮助,更多内容请关注职坐标编程语言Python频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved