码迷,mamicode.com
首页 > 编程语言 > 详细

Python基础(7)——迭代器&生成器

时间:2018-07-12 20:03:08      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:rom   需要   为什么   错误   func   instance   生成   done   ext   

1、列表生成式

1 [i*2 for i in range(10)]
2 [fun(i) for i in range(10)]

2、生成器

 1 # Author Qian Chenglong
 2 
 3 #列表生成器
 4 a=(i*2 for i in range(10))
 5 #a[1]#只是将算法存储了,只有在调用时才会生成相应的数据,不能直接读取
 6 a.__next__()#生成器只能一个一个往后取,且只存储当前值
 7 
 8 #函数生成器
 9 
10 # def fib(max):
11 #     n,a,b = 0,0,1
12 #     while n < max:
13 #         print(b)
14 #         a,b = b,a+b
15 #         n += 1
16 #     return ‘done‘
17 
18 #要把fib函数变成generator,只需要把print(b)改为yield b就可以了
19 def fib(max):
20     n,a,b = 0,0,1
21     while n < max:
22         #print(b)
23         yield  b
24         a,b = b,a+b
25         n += 1
26     return done#异常时存储的消息
27 
28 g=fib(10)
29 print(g.__next__())
30 #这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间当需要再重新调用这个函数,从上次yield的下一句开始执行。
31 
32 #生成器保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误(异常)。
33 
34 #异常处理
35 g = fib(6)
36 while True:
37      try:
38         x = next(g)
39         print(g:, x)
40 
41     except StopIteration as e:
42         print(Generator return value:, e.value)
43         break
44 
45 #通过生成器实现协程并行运算
46 import time
47 def consumer(name):
48     print("%s 准备吃包子啦!" %name)
49     while True:
50        baozi = yield
51 
52        print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
53 
54 
55 def producer(name):
56     c = consumer(A)
57     c2 = consumer(B)
58     c.__next__()
59     c2.__next__()
60     print("老子开始准备做包子啦!")
61     for i in range(10):
62         time.sleep(1)
63         print("做了2个包子!")
64         c.send(i)
65         c2.send(i)#把i的值传给yield,并到下一个yield
66 
67 producer("Dragon")

3、迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是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

  一般来说:生成器就是迭代器,迭代器不一定是生成器(下面不用看了,越看越不懂)

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

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

1 >>> isinstance(iter([]), Iterator)
2 True
3 >>> isinstance(iter(abc), Iterator)
4 True

你可能会问,为什么listdictstr等数据类型不是Iterator

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

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

Python基础(7)——迭代器&生成器

标签:rom   需要   为什么   错误   func   instance   生成   done   ext   

原文地址:https://www.cnblogs.com/long5683/p/9300815.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!