python之旅--迭代器生成器

生成器

在python中一边循环一边计算,称为生成器:generator。

列表生成式

#列表生成
>>> [i*2 for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

#不用生成式
>>> a = []
>>> for i in range(10):
...     a.append(i*2)
...
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

将列表生产式加括号就变成了生成器

生成器只有在调用时才会生成相应的数据。

#生成器只有一个方法 __next__()
#生成器只记录当前的位置
>>> a = (i*2 for i in range(10000))
>>> a
<generator object <genexpr> at 0x00000211522DB9E8>
>>> a.__next__()
0
>>> a.__next__()
2
>>> a.__next__()
4

函数变成生成器

#斐波那契数列
def fib(max):
    n,a,b = 0,0,1
    while n < max:
        #print(b)
        #想要将什么返回到就把yield放在相应位置
        #程序执行到yield处就中断,返回当前执行的值
        yield b #将print(b)改为yield就变成了生产器
        a,b = b,a+b
        n = n + 1
    return 'done'
f = fib(10)
f.__next__() #调用
#取全部用循环
for i in f:
    print(i)

#单线程下的并行效果 --> 协程
import time
def consumer(name):
    print("%s 开始消费" %name)
    while True:
        producter = yield
        print("%s 生产,%s 消费 " %(producter,name))
def producer(name):
    c = consumer('A')
    c2= consumer('B')
    c.__next__()
    c2.__next__()
    print("开始生产")
    for i in range(10):
        time.sleep(1)
        print("生产后分成两部分")
        c.send(i)
        c2.send(i)
producer('python')

 迭代器

可以直接作用于for循环的数据类型:

1.集合数据类型,如list、tuple、dict、set、str等。

2.generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

可以使用isinstance()判断一个对象是否是Iterable对象。

>>> from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance('abc',Iterable)
True
>>> isinstance((x for x in range(10)),Iterable)
True
>>> isinstance(100,Iterable)
False

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

可以使用isinstance()判断是否一个Iterator对象。

>>> from collections import Iterator
>>> isinstance((x for x in range(10)),Iterator)
True
>>> isinstance([],Iterator)
False
>>> isinstance({},Iterator)
False
>>> isinstance('abc',Iterator)

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

 >>> isinstance(iter([]),Iterator)

True

>>> isinstance(iter('abc'),Iterator)

True 

小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

Python的for循环本质上就是通过不断调用next()函数实现的,例如:

>>> for x in [1,2,3,4,5]:
...     pass

#上面等价于下面
#获得Iterator对象
>>> it = iter([1,2,3,4,5])
#循环
>>> while True:
...     try:
...             x = next(it) #获得下一个值
...     except StopIteration: #遇到StopIteration就退出循环
...             break

猜你喜欢

转载自www.cnblogs.com/wangzihong/p/9131170.html