生成器和迭代器

生成器

生成器生成的元素不会立即生成,当调用的时候才生成。所以,当要用到的数据是某种算法生成的时就可以使用生成器而不占用大量的空间,速度还很快,缺点是只能使用一次。

>>> a = (i+1 for i in range(10))
>>> a
<generator object <genexpr> at 0x000002BD6F607A40>
>>> a.__next__()
1
>>> a.__next__()
2
>>> a.__next__()

 

调用是可以用a.__next__() 或 next(a),当每次这样调用很麻烦,也可以使用for遇见迭代。

>>> a = (i+1 for i in range(10))
>>> for x in a:
...     print(x)
...
1
2
3
4
5
6
7
8
9
10

 

生成器也可以用于函数,是的函数也变成一个生成器,就像并行操作一样。

#!/usr/bin python3.5
#-*- coding:utf-8 -*-

'''
@auther: Starry
@file: fib.py 
@time: 18-1-19 下午10:30 
'''

def fib(Max):
    n, a, b = 0, 0, 1
    while n < Max:
        yield b
        a, b = b, a+b
        n += 1
    return '----stop-----'
g = fib(10)

while True:
    try:
        x = next(g)
        print('g:',x)
    except StopIteration as e:
        print('Generator return value:',e.value)
        break

  

由于生产器是当调用时运行,所以就像并行操作一样。

#!/usr/bin python3.5
#-*- coding:utf-8 -*-

'''
@auther: Starry
@file: 生产器并行.py 
@time: 18-1-19 下午10:49 
'''

import time

def cunsumer(name):
    print('%s 准备吃包子了!'%name)
    while True:
        baozi = yield

        print('包子[%s]来了,被[%s]吃了'%(baozi,name))

c = cunsumer('Starry')
c.__next__()
c.send('韭菜馅')

def producer(name):
    c = cunsumer('A')
    c1 = cunsumer('B')
    c.__next__()
    c1.__next__()
    print('开始准备做包子了!')
    for i in range(10):
        time.sleep(1)
        print('做了1个包子,分了两半')
        c.send(i)
        c1.send(i)

producer("STarry")

  

迭代器

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

可以被next()函数调用并不断返回下一个值的对象称为“迭代器”。Iterator

检查是否是“可迭代对象”:

>>> from collections import Iterable
>>>
>>> print(isinstance([],Iterable))
True
>>> print(isinstance({},Iterable))
True
>>> print(isinstance((),Iterable))
True
>>> print(isinstance('abc',Iterable))
True
>>> print(isinstance(10,Iterable))
False

  

见识是否是“迭代器”:

from collections import Iterator
print(isinstance([],Iterator))
print(isinstance((i for i in range(10)),Iterator))

  

 

posted @ 2018-04-04 21:59  starry_sky  阅读(207)  评论(0编辑  收藏  举报