美文网首页
24-生成器和迭代器

24-生成器和迭代器

作者: 胖腚猴 | 来源:发表于2017-09-17 17:54 被阅读0次

生成器和迭代器

迭代器

迭代器的作用:迭代器的目的就是为了“循环”,更加严谨一点,叫做"遍历"
迭代器是实现了对象中数据循环的操作方法,本质上是抽象的概念,经常把以下概念认为是迭代器:
对象中的next(),他是实现了迭代器的操作
具有迭代器的可迭代对象本身,他只是承载了迭代器具体操作的对象而已

列表和元组

列表和元组是有序的序列,所以可以直接通过索引获取每个值,索引+1就可以逐个获取,在内存中的操作就是将内存地址+1 获取下一个元素的内存地址,然后读取出来

集合和字典
集合和字典作为无序序列,无法通过索引获取每个值,这个时候就需要定义迭代器了。

迭代:概念(iteration)

迭代就是执行重复的特定的任务,直到任务完成位置。

相当于我们盖房子,今天添一块砖,明天加一张瓦,直到防止改完为止。这里每天的工作就是一次迭代。

迭代器协议(iterator protocol)

如果一个对象中包含了next()的魔术方法,那么这个对象就有了迭代器,这个对象不是迭代器

自定义迭代器:

#自定义一个迭代器

class DDQ:

    def __init__(self):
        #添加一个计数变量
        self.index = 0

    #定义了一个迭代器,该方法实现了迭代器,不是迭代器本身
    def __next__(self):
        i = self.index

        if i<10:
            #更新计数变量
            self.index +=1
            #为一次迭代返回值
            return i
        else:
            #停止迭代
            raise StopIteration

该迭代器制作完毕,并没有什么卵用,除非手动调用next()才可以迭代

ddq = DDQ()

#使用迭代器迭代数据

for i in ddq:
    print(i)

#错误信息:TypeError: 'DDQ' object is not iterable  该对象不可以迭代

以上操作实现了一个不可以迭代的迭代器!

可迭代协议 (iterator protocol)

可迭代协议包含2条要求:

1.对象中必须实现__iter__()的方法
2.这个__iter__()方法必须返回一个迭代器

注意:具有迭代器不一定可以迭代,有些对象没有实现可迭代操作

实现可迭代协议:

class DDQ:

    def __init__(self):
        #添加一个计数变量
        self.index = 0

    #定义可迭代协议
    def __iter__(self):
        return self
        

    #定义了一个迭代器,该方法实现了迭代器,不是迭代器本身
    def __next__(self):
        i = self.index

        if i<10:
            #更新计数变量
            self.index +=1
            #为一次迭代返回值
            return i
        else:
            #停止迭代
            raise StopIteration



#for..in迭代对象
kddq = DDQ()

for i in kddq:
    print(i)

大功告成:我们实现了可迭代协议,所以该对象可以迭代
完整的说法:这是一个具有迭代器(next)的可迭代(iter)对象(类)

迭代器相关的函数

iter() 获取一个对象的迭代器

格式:iter(对象)
返回:迭代器

next() 进行一次迭代操作

格式:next(迭代器)
返回值:迭代器返回值

迭代器的操作

1.手动迭代

next(迭代器)  获取第1个值
next(迭代器)  获取第2个值
...
next(迭代器)  获取第n个值
...
迭代终止

2.循环迭代

for .. in 可迭代对象:

    在循环中使用next(迭代器)实现了迭代。

总结:

1.一般情况下,迭代器都是可迭代的。但是也有不可以迭代的。   
2.字典和集合中一定是有迭代器,并且可以迭代

生成器:

生成器可以理解为一种数据类型,他并不是,因为他也是迭代器的一种,是一种非常特殊的迭代器
生成器本身实现了iter 可迭代协议,但是并没有实现迭代器协议?、

迭代器协议呢?

生成器就是要实现迭代器协议,但是语法和操作和迭代器有很大的区别。

生成器的优点:

生成器对python中的延迟操作提供了支持。操作不需要一次完成,只需要在需要的时候进行操作即可

延迟操作的别名:惰性求值

处理大数据和超大文件等操作,生成器非常有效的。

生成器分类:

1.生成器表达式

元组内涵/元组推导式 的结果就是制作一个生成器,生成器的结果是一个对象


#生成器/元组推导式

tuple1 = (1,2,3,4,5,6,7,8,9)

scq = (i for i in tuple1)

print(scq)

2.生成器函数

正常声明函数就可以了,生成器中使用yield语句而不是return语句,生成器的结果是一个对象

#h函数生成器

def myfunc():
    yield 1
    yield 2
    yield 3
    yield 4

scq2 =  myfunc()
print(scq2)

调用生成器:

1.手动调用

next(生成器)  获取第1个值
next(生成器)  获取第2个值
...
next(生成器)  获取第n个值
...
迭代终止

2.循环调用

for .. in 可迭代对象:

    在循环中使用获取yield的值实现了迭代。

生成器函数

send() 向生成器中传入一个数据

格式:生成器.send(值)

在生成器函数中

    变量 = (yield 其他变量)

close() 关闭生成器结束迭代

格式:生成器.close()

效率问题:

不能单独进行比较,这两个操作适用于不同的环境。

对于小数据而言,使用迭代器操作更加方便可靠。
对于大数据而言,使用迭代器容易玩崩,推荐使用生成器

在遍历10个G的文件时,内存只有2个G

使用迭代器是无法操作的,迭代器需要将数据预先准备好才可以迭代,2G内存装下10G文件那就呵呵了~!

使用生成器是非常理想,生成器处理多少文件数据,就占用多少内存,处理完这点数据还会清空,在此利用内存,2G内存处理10G文件绰绰有余

最后!生成器的缺陷

生成器只能迭代一次!

相关文章

网友评论

      本文标题:24-生成器和迭代器

      本文链接:https://www.haomeiwen.com/subject/galmsxtx.html