# Python3.5——迭代器与生成器（上）

1、列表生成式

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

#列表生成式
a = [i*2 for i in range(10)]
print(a)

#运行结果：
#[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

2、生成器

（1）将一个列表生成式的[]改成()，就创建一个生成器。代码：b = (i*2 for i in range(10))

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

#列表生成式
a = [i*2 for i in range(10)]
print(a)
print("type of a:",type(a))

#生成器
b = (i*2 for i in range(10))
print(b)
print("type of b:",type(b))
for i in b:
print(i)

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
type of a: <class 'list'>
<generator object <genexpr> at 0x008B8D20>
type of b: <class 'generator'>
0
2
4
6
8
10
12
14
16
18

#生成器
b = (i*2 for i in range(10))
print(next(b))
print(next(b))
print(next(b))
print(next(b))
#运行结果：
#0
#2
#4
#6

（2）当推算的算法比较复杂时，用类似列表生成式的for循环无法实现，还可以用函数来实现生成器

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

def fibonaccl(max):
n,a,b = 0,0,1
while n < max:
print(b)
a,b = b,a + b
n = n + 1
return 'done'

fibonaccl(10)

1
1
2
3
5
8
13
21
34
55

Fibonaccl函数和生成器generator只有一步之遥，要Fibonaccl函数变成生成器generator，只需要将print(b)修改为yield b就可以了。

def fibonaccl(max):
n,a,b = 0,0,1
while n < max:
yield b
a,b = b,a + b
n = n + 1
return 'done'

print(fibonaccl(15))

f = fibonaccl(15)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("===========")
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("=========start loop========")    #接着打印后边的元素
for i in f:
print(i)

<generator object fibonaccl at 0x00548D50>
1
1
2
3
===========
5
8
13
21
=========start loop========
34
55
89
144
233
377
610

def fibonaccl(max):
n,a,b = 0,0,1
while n < max:
yield b
a,b = b,a + b
n = n + 1
return 'done'
g = fibonaccl(6)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e:
print('Generator return value:', e.value)
break

g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

3、生成器并行的实现——单线程下的并行效果

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

#生成器并行的实现——生产者、消费者模型
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield         #yield保存当前状态返回

print("包子[%s]来了,被[%s]吃了!" %(baozi,name))

def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()         #next只唤醒yield
c2.__next__()
print("开始准备做包子啦!")
for i in range(3):
time.sleep(1)
print("做了2个包子!")
c.send(i)          #send唤醒yield同时给它传值
c2.send(i)

producer("alex")

A 准备吃包子啦!
B 准备吃包子啦!