day12-1 迭代器和生成器

通过yield实现单线程的情况下并发运算的效果

 1 import time
 2 
 3 def consumer(name):
 4     print("%s 准备吃包子了!!" % name)
 5     while True:
 6         baozi = yield
 7         
 8         print("包子[%s]来了,被[%s]吃了" %(baozi,name))
 9 #c = consumer('RI')
10 # =============================================================================
11 # c.__next__()
12 # b1 = "白菜馅"
13 # c.send(b1)  # send调用yield 同时给yield传值。next只会唤醒yield
14 # c.__next__()
15 # 
16 # =============================================================================
17 def producer(*name):
18     c1 = consumer(name[0])   # 调用函数把他变成·生成器·
19     c2 = consumer(name[1])
20     next(c1)  # 为了打印  "%s 准备吃包子了!!" % name  这句话
21     next(c2)
22     print('RICH 开始做包子了')
23     for i in range(10):
24         time.sleep(i+2)
25         print('做了两个包子')
26         c1.send(i)
27         c2.send(i)
28     print('RICH 累了,下班!')
29 
30 name = ('A1','B1')
31 
32 producer(*name)
33 # =============================================================================
34 # 
35 # 包子[8]来了,被[A1]吃了
36 # 包子[8]来了,被[B1]吃了
37 # 做了两个包子
38 # 包子[9]来了,被[A1]吃了
39 # 包子[9]来了,被[B1]吃了
40 # RICH 累了,下班!
41 # =============================================================================
通过生成器实现协程并行运算

关于可迭代对象和迭代器的相关知识

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

 一种是数据集合类型 如 list tuple dict set str
 一种是generator 包括生成器 和带yield 的generator function
 

这些可直接作用于for 循环的对象统称为可迭代对象 Iterable,可以使用Isinstance判断一个对象是不是可迭代对象

1 # =============================================================================
2 #  isinstance('abc',Iterable)
3 # Out[53]: True
4 # 
5 # isinstance([],Iterable)
6 # Out[54]: True
7 #  可迭代返回True
8 # =============================================================================
生成器不但可以用于for 循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration 的异常,表示无法进行下一个值

#可以被next()函数调用并返回的下一个值得=的对象成为迭代器 Iterator, 可以使用isinstance 判断一个对象是不是可迭代对象 Iterator

1 # =============================================================================
2 #  isinstance((x+1 for i in range(10)),Iterator)
3 # Out[56]: True
4 # 
5 # =============================================================================
6  

# 列表,字典 str 等式是可迭代对象,但不是迭代器
# 把可迭代对象变为迭代器 可以使用Iter() 函数

1 a = [1,2,3,4]
2 
3 b = iter(a)
4 
5 isinstance(a,Iterator)
6 Out[59]: False
7 
8 isinstance(b,Iterator)
9 Out[60]: True

python 的Iterator 对象表示的是一个数据流,Itrator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration 错误。可以把数据流看做是一个有序序列。

但是我们不知道有序序列的长度,只有通过next()不断调用计算下一个数据。所以Iterator 是惰性的,只有在需要时才会返回下一个数据时他才会计算。

Iterator 甚至可以返回一个无限大的数据流。例如全体自然数,而list是永远不可能存储全体自然数的

小结:

可以作用于for循环的就是Iterable类型

凡是可以作用于next()对象的则是Iterable类型。表示一个惰性计算的序列

Iterable 对象可以通过iter()获得iterator对象

python for循环的本质是通过不断调用next()函数实现的

 1 for i in [1,2,3,4,5,6]:
 2     print(i)
 3 
 4 # 相当于
 5 it = iter([1,2,3,4,5])
 6 
 7 while True:
 8     try:
 9         x = next(it)
10         print("it",x)
11     except StopIteration:
12         break
13 
14 
15 # =============================================================================
16 # 1
17 # 2
18 # 3
19 # 4
20 # 5
21 # 6
22 # it 1
23 # it 2
24 # it 3
25 # it 4
26 # it 5
27 # =============================================================================

t = range(10)

也是相当于迭代器,查看文件 for line in f:  也是相当于一个迭代器。因为它不用先生成一个列表,所以感觉比较快

原文地址:https://www.cnblogs.com/yfjly/p/9790196.html