Fork me on GitHub

python之路之迭代器与生成器

一  迭代器

那么在研究迭代器之前首先应该要知道什么是迭代。

迭代:是一个重复的过程,并且每次重复都是建立基于上一次的结果而来的,所以在迭代的过程其实是在不断变化的。

迭代器:就是迭代取值的工具。

那么对于这个工具的使用,在python使用迭代的方法就是使用内置的——iter——,换言之就是说能够调用该方法的都叫可迭代的对象

那么对于迭代器的优缺点:

优点就是:1 提供一种不依赖于索引的取之方式。

                  2 更加省内存,因迭代器运行时每次只取一个值,

缺点:取值麻烦,只能一个一个取,而且只能向后取,全部的值只能取一次,没办法用len获取长度。

迭代器对象:可迭代的对象执行--iter--方法得到的返回值即使迭代器对象。

迭代器对象一定是可迭代的对象,而可迭代的对象不一定是迭代器对象。

 

s='hello'
inter_s=s.__iter__()
while True:
    try:
         print(inter_s.__next__())
    except StopIteration:
        break
那么一般平时比较常用的列表,字典,元组,file等都是可迭代对象,那么其中有一个比较特殊的就是file,因file本身就是迭代器对象既能调用--itrer也能调用--next--,

调用iter时,结果还是它本身。


迭代器最典型的例子就是for循环:

for line in l:那么for循环首先对l做一个调用--iter--的操作,拿到迭代器,然后再通过调用--next--拿到返回值,赋值给line.


for循环自动检测stopiteration。在值取尽时,结束for循环。


二 生成器

函数内含有yield关键字,再调用函数就不会执行函数体代码,拿到的返回值就是一个生成器对象。

f=open('a.txt','r',)
f.__next__()
f.__iter__()
def chicken():
    print('--------1')
    yield 1
    print('=======2')
    yield 2
    print('-----3')
    yield 3

obj=chicken()
print(obj)

# print(obj.__next__())
print(obj.__iter__().__next__())#生成器的本质就是迭代器
print(obj.__iter__().__next__())
print(obj.__iter__().__next__())
 

生成器本质就是迭代器
def rang():
    print('===')
    n = 0
    while True:
     yield n
     n+=1

obj=rang()
# print(obj)
print(obj.__next__())
print(obj.__next__())#第二次执行时会从yield开始,所以yield保持程序运行的状态。
print(obj.__next__())
# for item in obj:
#     print(item)

 

生成一种迭代器,相当于for循环

def rang(start,stop,step):
    n=start
    while n<stop:
        yield n
        n+=step

obj=rang(2,8,2)
print(obj.__next__())
print(obj.__next__())
# for item in obj:
#     print(item)


就相当于
for item in range(2,8,2):
    print(item)

总结生成器:

1 给我们提供一种自定义迭代器的方式,可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器。

2 yield可以象return一样用于返回值,区别是return只能返回一次值,而yield可以返回多次,因程序遇见return就会结束,yield可以保存函数的一个执行状态。


协程函数:
#yield关键字的另外一种使用形式:表达式形式的yield
def eater(name):
    print('%s 准备开始吃饭啦' %name)
    food_list=[]
    while True:
        food=yield food_list
        print('%s 吃了 %s' % (name,food))
        food_list.append(food)

g=eater('Feng')
g.send(None) #对于表达式形式的yield,在使用时,第一次必须传None,g.send(None)等同于next(g)
g.send('烤鸡')
g.send('烤鸭')
g.send('猴脑')
g.send('熊掌')
g.close()
g.send('鱼刺')
g.send('鲍鱼')


面向过程编程:
优点:将复杂流程化,进而简化。

缺点:修改一个阶段,可能其他阶段也要修改,所以容错率低,改进麻烦。

posted @ 2018-03-30 20:35  道阻切长  阅读(220)  评论(4编辑  收藏  举报