生成器(generator):在 Python 中,不必创建完整的 list,从而节省大量的空间。一边循环一边计算的机制。

创建一个 generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的 [] 改成 () ,就创建了一个 generator:

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

  如果要一个一个打印出来,可以通过 next() 函数获得 generator 的下一个返回值:

>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
...
...
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):File "<stdin>", line 1, in <module> StopIteration

  generator 保存的是算法,每次调用 next(g) ,就计算出 g 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration 的错误。

常用的方法是使用for 循环,因为 generator 也是可迭代对象:

>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81

  

generator 非常强大。如果推算的算法比较复杂,用类似列表生成式的 for循环无法实现的时候,还可以用函数来实现。

  比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:  

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

  斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(max):
  n, a, b = 0, 0, 1
  while n < max:
    print(b)
    a, b = b, a + b
    n = n + 1
  return 'done'
>>> fib(6)
1
1
2
3
5
8
'done'

  

  

上面的函数和 generator 仅一步之遥。要把 fib 函数变成generator,只需要把 print(b) 改为 yield b 就可以了:

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

  如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个 generator:

>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>

  函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而变成generator 的函数,在每次调用 next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。

for 循环调用 generator 时,发现拿不到 generator 的 return 语句的返回值。如果想要拿到返回值,必须捕获 StopIteration 错误,返回值包含在 StopIteration 的 value 中:

>>> g = fib(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

 

小结
  generator 是非常强大的工具,在 Python 中,可以简单地把列表生成式改成 generator,也可以通过函数实现复杂逻辑的 generator。

  要理解 generator 的工作原理,它是在 for 循环的过程中不断计算出下一个元素,并在适当的条件结束 for 循环。对于函数改成的 generator 来说,遇到 return 语句或者执行到函数体最后一行语句,就是结束 generator的指令, for 循环随之结束。

 

(十)python3 生成器的更多相关文章

  1. 第十三天python3 生成器yield

    生成器generator 生成器指的是生成器对象,可由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象: 生成器函数 函数体中包含yield语句的函数,返 ...

  2. python3 生成器&迭代器

    #Author by Andy#_*_ coding:utf-8 _*_import timefrom collections import Iterable#列表生成式def func(): lis ...

  3. python3 生成器初识 NLP第五条

    话不多说,先把第五条抄一遍: 五,沟通的意义在于对方的回应 沟通没有对与错,只有“有效果”或者“没有效果”之分. 自己说得多“对”没有意义,对方收到你想表达的讯息才是沟通的意义. 因此自己说什么不重要 ...

  4. python3 生成器和生成器表达式

    ''' 生成器:函数中有yield就是生成器函数 生成器本质是一个迭代器 yield后面的值会作为返回值返回. ''' def func(): print("apple") pri ...

  5. Python3 生成器

    生成器(genetor): 1>生成器只有在调用的时候才会生成相应的数据: 2>生成器只记录当前位置,有一个__next__()方法 3>yield可以实现单线程先的并发运算 1.列 ...

  6. python3 生成器表达式

    生成器表达式 [i for i in range(100)] #列表解析 与列表解析的不同是,列表解析用中括号,生成器表达式用小括号 g = (i for i in range(1000)) #生成器 ...

  7. python3 - 生成器genarator

    在Python中,这种一边循环一边计算的机制,称为生成器:generator. 生成器保存的是算法,每次调用 next() ,就计算出 下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 ...

  8. python3 生成器笔记

    #生成器def MyDemo(M): for i in range(M): yield i**2for item in MyDemo(9): print(item) # #生成器import sysa ...

  9. 净心诀---python3生成器进阶

    列表推导式 把需要用一个函数写成的小功能,利用一行表达式完成 例子: l = [1,2,3,4,5] # 所有的偶数都放到新的列表中 # 正常函数 def Lst(): li = [] for i i ...

随机推荐

  1. bzoj2720: [Violet 5]列队春游(概率期望+组合数学)

    Description Input Output Sample Input   Sample Output   HINT 数学题都这么骚的么……怎么推出来的啊……我是真的想不出来…… 首先,要算总的视 ...

  2. Noip2014生活大爆炸版石头剪刀布【水模拟】

    模拟暴力也要优雅. https://www.luogu.org/problemnew/show/P1328 像我这种蒟蒻就会敲无数个ifelse qaq. 可以优雅地进行预处理一下. 膜法真是好东西q ...

  3. Python实现判断回文串

    回文数的概念:即是给定一个数,这个数顺读和逆读都是一样的.例如:121,1221,a,aa是回文数,123,1231不是回文数.  while 1: String = input('请先输入一个字符串 ...

  4. C语言经典程序1

    //打印2-200的所有素数 (除了1和它本身,不能被小于它的其它数整除的数称为素数) ; ;i<;i++) //i遍历2-200 { ; //先默认这个数为素数 ;j<i-;j++) / ...

  5. [SRM613~] TaroCheckers

    一定要注意Topcoder的提交机制 Links: 原题地址 Vjudge Solution 这道题思维比较巧妙. 一看就基本知道是一个Dp题. 首先转换一下,用列而不是行来设第一维的状态,因为每列只 ...

  6. Hdu 3488 Tour (KM 有向环覆盖)

    题目链接: Hdu 3488 Tour 题目描述: 有n个节点,m条有权单向路,要求用一个或者多个环覆盖所有的节点.每个节点只能出现在一个环中,每个环中至少有两个节点.问最小边权花费为多少? 解题思路 ...

  7. 51nod1099 任务执行顺序

    #include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; int r,o; int s ...

  8. 简单备份11g db (文件系统)

    1.more check.sqlsqlplus / as sysdba << EOF!banner start dbstartupselect name from v\$database; ...

  9. echart分组柱形图绑定数据

    <!DOCTYPE html> <head> <meta charset="utf-8"> <title>ECharts </ ...

  10. SpringMVC与请求控制器

    MVC设计模式 视图(View)      -对应组件:JSP或者HTML文件 控制器(controller) -对应组件:Servlet 模型(Model)   -对应组件:JavaBean MVC ...