Python3 生成器的练习

生成器的各种练习

 

生成器有两种创建方式:

1. 生成器函数

  拥有yield关键字的即是生成器函数

  生成器函数特点: 调用生成器函数直接返回生成器的引用, 不执行函数内部代码, 每取一个值就执行代码段,遇到yield返回所取值

  生成器取值:

  1. next(generator) or generator.__next()方法取值
  2. generator.send(value) 取值, 用法与next相同,只是会把发送的值保存到上一个yield的变量中, 不能用在第一个和最后一个yield
  3. for xxx in generator: 利用for循环遍历取值,取完为止
  4. 数据类型的强制转换 如list(generator)

2.  生成器表达式

  所有的生成器本身也是个迭代器,生成器表达式方式如下

  g = ( value for value in Iterable if value ...) 

 

生成器的一些demo

demo1: 生成器的取值问题

def demo():
    for i in range(4):
        yield i

g = demo()

g1 = (i for i in g)
g2 = (i for i in g1)

print(list(g1))
print(list(g2))
View Code
[0, 1, 2, 3]
[]

理解: 
# g, g1, g2 并没有开始取值,只是一个生成器,
# 当执行完第一个类型强制转换后, g1生成器内部已经没有值了, 
# 所以执行第二个类型转换, 'i for in g1' 这个操作时,遍历的是一个空列表,g2生成器转换的是一个控列表
out

 

demo2:生成器的取值问题2

def add(n, i):
    return n + i


def test():
    for i in range(4):
        yield i


g = test()
for n in [1, 10]:
    g = (add(n, i) for i in g)

print(list(g))

g = test()
for n in [1, 10]:
    g = (add(n, i) for i in g)
    g = list(g)

print(list(g))
View Code
[20, 21, 22, 23]
[11, 12, 13, 14]

理解:
"""
第一处可以把代码分开理解
g = test()
n = 1
g = (add(n, 1) for i in g) ->>> 此处g并未被取值
n = 10 
g = (add(n, 1) for i in g) ->>> 可以翻译成 
g = (add(n, 1) for i in (add(n, 1) for i in test()) ->>> test是初始的生成器,此时生成器均未被取值 
当执行list(g)时才开始取值 此时n=10 所以结果是 [20, 21, 22, 23]

第二处便好理解了, 每循环一次, 生成器便开始强制转换取值, 最后便是 [11, 12, 13, 14]
"""
out

 

 demo3: 生成器的预激活, send方法取值

 1 # coding=utf-8
 2 
 3 """
 4 功能:每次向一个容器里扔一个数, 返回这些数的最小值, 最大值, 平均值
 5 要求: 用生成器实现
 6 """
 7 
 8 
 9 def init(func):
10     def inner(*args, **kwargs):
11         g = func(*args, **kwargs)
12         next(g)
13         return g
14     return inner
15 
16 
17 @init
18 def statistics():
19     count = sum = avg = 0
20     min = None
21     max = None
22     while True:
23         data = yield {'min': min, 'max': max, 'avg': avg}
24         if min is None:
25             min = data
26             max = data
27             avg = data
28             count = 1
29             sum = data
30         else:
31             if data < min:
32                 min = data
33             if data > min:
34                 max = data
35             sum += data
36             count += 1
37             avg = sum / count
38 
39 
40 if __name__ == '__main__':
41     s = statistics()
42     print(s.send(-10))
43     print(s.send(-5))
44     print(s.send(30))
View Code
{'min': -10, 'avg': -10, 'max': -10}
{'min': -10, 'avg': -7.5, 'max': -5}
{'min': -10, 'avg': 5.0, 'max': 30}
out

 

 

 参考:  

 python之路——迭代器和生成器

 
 
 
 
 
posted @ 2018-11-16 14:10  yscl  阅读(135)  评论(0)    收藏  举报