终端命令行执行>>> a = [1,2,3]>>> [i*2 for i in range(10)]-----------------输出结果-----------------[0,2, 4, 6, 8, 10, 12, 14, 16, 18]
列表生成器


终端执行:>>> ( i*2 for i in range(10))-------------------输出结果------------------------
 at 0x00000000021859E8>
>>>b = ( i*2 for i in range(10))>>> for i inb:
...print(i)-------------------输出结果-------------------------02
4
6
8
10
12
14
16
18
range
生成器 只有在调用时才会生成相应的数据
只记住当前位置
只有一个__next__()方法
1 a = (i*2 for i in range(100))2 print(a.__next__())3 print(a.__next__())4 print(a.__next__())5 print(a.__next__())6 ---------------输出结果-------------------
7 08 2
9 4
10 6
我们创建了一个generator(生成器)后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误
generator(生成器)非常强大,如果推算的算法比较复杂,用列斯列表生成式的for循环无法实现的时候,还可以用函数来实现
2.1 斐波那契数列
菲波纳契数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到
1 deffib(max):2 n, a, b = 0, 0, 1
3 while (n 
7
8 fib(10)9 ---------------------------------------
10 1
11 1
12 2
13 3
14 5
15 8
16 13
17 21
18 34
19 55
2.2 yield
1 def fib(max):2 n,a,b = 0,0,1
3 while (n < max):4 yieldb5 a,b = b, a+b6 n += 1
7 f = fib(10)8 for i in range(10):9 print(f.__next__())10 --------------输出结果-----------------
11 1
12 1
13 2
14 3
15 5
16 8
17 13
18 21
19 34
20 55
2.3 yield 实现单线程并行


1 importtime2 defconsumer(name):3 whileTrue:4 baozi = yield
5 print("包子[%s]来了,被[%s]吃了" %(baozi,name))6
7
8 c = consumer("wsy")9 c.__next__()10
11 defproducer(name):12 c = consumer('猫')13 c2 = consumer('狗')14 c.__next__()15 c2.__next__()16 print("开始吃")17 for i in range(10):18 time.sleep(1)19 print("做了1个包子,分两半")20 c.send(i)21 c2.send(i)22 producer("wsy")23 ---------------------------结果------------------------
24 开始吃25 做了1个包子,分两半26 包子[0]来了,被[猫]吃了27 包子[0]来了,被[狗]吃了28 做了1个包子,分两半29 包子[1]来了,被[猫]吃了30 包子[1]来了,被[狗]吃了31 做了1个包子,分两半32 包子[2]来了,被[猫]吃了33 包子[2]来了,被[狗]吃了34 做了1个包子,分两半35 包子[3]来了,被[猫]吃了36 包子[3]来了,被[狗]吃了37 做了1个包子,分两半38 包子[4]来了,被[猫]吃了39 包子[4]来了,被[狗]吃了40 做了1个包子,分两半41 包子[5]来了,被[猫]吃了42 包子[5]来了,被[狗]吃了43 做了1个包子,分两半44 包子[6]来了,被[猫]吃了45 包子[6]来了,被[狗]吃了46 做了1个包子,分两半47 包子[7]来了,被[猫]吃了48 包子[7]来了,被[狗]吃了49 做了1个包子,分两半50 包子[8]来了,被[猫]吃了51 包子[8]来了,被[狗]吃了52 做了1个包子,分两半53 包子[9]来了,被[猫]吃了54 包子[9]来了,被[狗]吃了
吃包子例子
3.迭代器
我们已经知道,可以直接作用于for循环的数据类型有一下几种:
1.集合数据类型,如list,tuple,dict,set,str等
2.生成器,包括生成器和带yield的generator function
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable
可以使用isinstance()判断一个对象是否是Iterable对象:


1 命令行2 >>> from collections importIterable3 >>>isinstance([],Iterable)4 True5 >>>isinstance({},Iterable)6 True7 >>> isinstance('abc',Iterable)8 True9 >>> isinstance((x for x in range(10)),Iterable)10 True11 >>> isinstance(100,Iterable)12 False
判断是否为iterable对象
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,知道最后抛出StopIteration错误表示无法继续返回下一个值了。
*可以被next()函数调用并不断返回下一个值得对象成为迭代器:Iterator
可以使用isinstance()判断一个对象是否是Iterator对象:
#结论:生成器一定是迭代器 迭代器不一定是生成器
生成器都是Iterator(迭代器)对象,但list,dict,str虽然是iterable(可迭代)却不是Iterator(迭代器)
把list,dict,str等Iterable变成Iterator可以使用iter()函数:
1 >>>a2 [1, 2, 3]3 >>>iter(a)4 
5 >>> b =iter(a)6 >>> b.__next__()7 1
8 >>> b.__next__()9 2
10 >>> b.__next__()
只要有next()函数 一定是迭代器