Generators functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.
https://wiki.python.org/moin/Generators
翻译:生成器功能允许你声明一个行为类似于迭代器的函数,它也能用在for循环中。
yield关键字类似于return,不同之处在于Python的return返回一个值(或者一个set),而yield返回的是一个生成器对象,下面将详细解释什么是生成器。
Python生成器是Python独有的高级特性,其也是用来实现迭代的操作,生成器自动实现了迭代器协议,是可迭代对象之一,它的存在增强了Python的简便性。
定义生成器有2种方法:
类似于列表表达式,只要将列表表达式的[列表形式 生成规则]
的“[]”改为“()”,就得到了一个生成器的表达式,返回一个生成器对象。这里不再介绍生成器表达式,参见列表表达式。
>>> (x * x for x in range(1,11))
at 0x03740CF0> #是个对象
>>> list((x * x for x in range(1,11)))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>>
即以定义函数的形式定义生成器,区别在于return关键字改成yield,返回值是一个generator对象。
>>> def generator():
... list = range(6)
... for i in list:
... yield i * i
...
>>> print(generator())
0x03740F60> #是个对象
>>> g = generator()
>>> for i in g:
... print(i)
...
0
1
4
9
16
25
>>>
生成器函数和普通的函数执行流程不一样,函数是顺序执行,碰到return即返回,而生成器函数也可以像Java迭代那样可以用next()函数来取下一个值,取到穷尽也会报错。
但是,如果一个函数里有yileld关键字,那么当你调用这个函数时,函数内部代码并不会立即执行,仅仅返回一个空的对象。函数代码真正执行在使用for语句进行迭代时,每次迭代返回一个值后,然后进行下一次循环,yield关键字将挂起该生成器函数的状态,并且保留函数信息。这样做的好处是,所有的结果并不是在一瞬间产生的,而是有所延迟,在大规模数据处理中将受益无穷。
参考资料:
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014317799226173f45ce40636141b6abc8424e12b5fb27000
http://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html
摘录:
迭代是一个实现可迭代对象(实现的是 iter() 方法)和迭代器(实现的是 next() 方法)的过程。可迭代对象是你可以从其获取到一个迭代器的任一对象。迭代器是那些允许你迭代可迭代对象的对象。
翻译自stackoverflow。
补充内容:
语法上和函数类似:生成器函数和常规函数几乎是一样的。它们都是使用def语句进行定义,差别在于,生成器使用yield语句返回一个值,而常规函数使用return语句返回一个值
自动实现迭代器协议:对于生成器,Python会自动实现迭代器协议,以便应用到迭代背景中(如for循环,sum函数)。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,在没有值可以返回的时候,生成器自动产生StopIteration异常
状态挂起:生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行
Python生成器有什么优点
https://www.zhihu.com/question/24807364