Python基础——迭代器&生成器

Posted 一抹烟霞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python基础——迭代器&生成器相关的知识,希望对你有一定的参考价值。

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基础——迭代器&生成器的主要内容,如果未能解决你的问题,请参考以下文章

python-基础 生成式 生成器 迭代器 JSON pickl

Python 迭代器&生成器,装饰器,递归,算法基础:二分查找二维数组转换,正则表达式,作业:计算器开发

Day4 - Python基础4 迭代器装饰器软件开发规范

Python学习之旅 —— 基础篇字符串格式化递归生成器&迭代器模块

Day4 - Python基础4 迭代器装饰器软件开发规范

Python基础-4