迭代器与生成器

迭代:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来

while True:
    print('=------->')

    l=[1,2,3,4,5,6]
    n=0
    while n < len(l):
        print(l[n])
        n+=1
这个循环就是每次重复都是基于上一次的结果而来。

2、要想了解迭代器到底是什么,就必须先了解一个概念。即什么是可迭代的对象?

可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代对象 

以下都是可迭代的对象   它们的内置中都有__iter__方法。

字符串:  str='hello'
列表:    list=[1,2,3]
元组:    tup1=(1,2,3)
字典:    dic={'x':1}
集合:     s1={'a','b','c'}
文件:    f=open('a.txt','w',encoding='utf-8')

用法如下:

 dic={'x':1,'y':2,'z':3}
 iter_dic=dic.__iter__()

3、迭代器对象:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象。

       以下是迭代器对象。

      特点是他们都带有__next__的方法。


列表 list1=[1,2,3]
字典 dic
={'x':1,'y':2,'z':3} 集合 s1={'a','b','c'}


如下:

dic={'x':1,'y':2,'z':3}
iter_dic=dic.__iter__()
iter_dic.__next__())

4、可迭代的对象VS 迭代器对象?

可迭代的对象:str,    list,    tuple,   dic,     set,     file

1、获取可迭代对象的方式:无须获取,python内置:str,    list,    tuple,   dic,     set,     file都是可迭代对象。

2、特点:

内置__iter__方法都叫可迭代的对象,执行该方法会拿到一个迭代器对象

迭代器对象:文件对象本身就是迭代器对象

1、获取迭代器对象的方式:

执行可迭代对象的__iter__的方法,拿到的返回值就是迭代器对象

2:特点:

内置有__next__方法,该执行方法会拿到迭代器对象中的一个值

内置有__iter__方法,执行该方法会拿到迭代器本身

迭代器的优缺点

1、迭代器的优点

1、提供了一种可以不依赖于索引的取值方式

l=open('a.txt','r',encoding='utf-8')
iter_l=l.__iter__()
while True:
    try:   
        print(iter_l.__next__())
    except StopIteration:
        break

2、迭代器更加节省内存

同样 有优点  就有缺点,

缺点1:取值麻烦,只能一个一个取,只能往后取,

缺点2:并且是一次性,无法用len获取长度。

3、for 循环原理分析:

1:for循环称之为迭代器循环,in后跟的必须是可迭代的对象:

2:for循环会执行in后对象的__iter__方法,拿到迭代器对象。

3:然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体。

4:周而复始,直到取值完毕, for循环会检测到异常自动结束循环。

生成器:

函数内包yield 关键字,

再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象

def chicken():
    print('=====>first')
    yield 1   #保函 yield,到这个yield后暂停不动,这个1就是返回值,也是              生成器的对象
    print('=====>sencond')
    yield 2
    print('=====>third')
    yield 3


obj=chicken()

生成器的本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法。

所以他的循环也是遵循迭代器用法

def chicken():
    print('=====>first')
    yield 1 
    print('=====>sencond')
    yield 2
    print('=====>third')
    yield 3


obj=chicken()

for item in obj:
    print(item)

#打印结果:
=====>first
1
=====>sencond
2
=====>third
3

#第一步 iter_obj=obj.__iter__(),拿到迭代器,
第2步;出发iter_obj._next_(),拿到该方法的返回值,赋值给item,
第3步 周而复始,直到函数内不再有yield,即取值完毕。
第4步,for会检测导StopIteration异常,结束循环。

总结yield:

1:为我们提供了一种自定义迭代器的方式,

可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器。

2:yield可以让return一样用于返回值,区别是return值能返回一次值,变结束,二yield可以返回多次值,因为yield可以保存函数的执行的状态。

def my_range():
        print('start.......')
        n=0
        while True:
            yield n
            n+=1

obj =my_range()
print(obj)
for i in my_range():
    print(i)


#打印结果
1
2
3
4
5
6
7
8
。
。
。
。
。
。
一直到无穷大。就是因为yield只是暂停。

3、生成器yield的表达形式:

第一步、必须初始化一次, 让函数停在yield的位置,

第二部:然后在send给yield传值, send有两个作用, 一个给yield传值,一个是当__next__的功能使用。

def eat(name):
    print('%s ready to eat'%name)
    food_list=[]
    while True:
        food =yield
        food_list.append(food)
        print('%s start to %s'%(name,food))

dog1=eat('alex')
res0=dog1.__next__()     #第一次 先调用__next__(),让函数停在这里
# print(res0)
res1=dog1.send('')      #然后send给yield传值。

#打印结果
alex ready to eat
alex start to 肉
['']
alex start to 麻辣烫
['', '麻辣烫']
原文地址:https://www.cnblogs.com/lx3822/p/8684620.html