[译]yield关键字都作了什么?

原文: https://stackoverflow.com/que...

个人微信公众号:python每日一练python

要理解什么是 yield,必须理解什么是生成器(generator)。在理解生成器以前,让咱们先了解迭代。微信

迭代函数

当你创建了一个列表,你能够逐个地访问这个列表的元素,而这个访问的过程叫作迭代(iteration)code

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

代码中的mylist就是一个可迭代对象(iterable),当你使用列表生成式时,你就建立了一个list,同时也建立了一个可迭代对象:对象

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

凡是能使用for...in...语句的对象,都叫作可迭代对象,例如:liststring、文件等等内存

这些可迭代对象很是方便,由于你能够根据本身的须要来访问它们。可是同时也须要将全部的值存入内存当中,不管你是否是须要全部的值,可能对于一个列表[x for x in range(100000)],你仅仅想拿到里面的素数,但当这个列表生成式被执行的时候,已经将全部100000个数字存入了内存中。get

生成器generator

生成器是一种只能迭代一次的迭代器,生成器不会一次将全部的元素存入内存中,而是一边迭代一边运算:string

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4

这份代码看起来和上面的代码没有什么区别。可是你不能再次执行for i in mygenerator,由于生成器只能使用一次:it

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...     print(i)
...
0
1
4
>>> for i in mygenerator:
...     print(i)
...
>>>

Yield

yield的使用和return的使用没什么区别,只是yield会返回一个生成器

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # 建立一个生成器
>>> print(mygenerator) # mygenerator是一个对象!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4

当你的函数须要返回一个很大的元素集合,而且每一个元素只须要用到一次的时候,使用yield会很是方便

要想理解yield,你必须理解当你调用一个包含yield的函数的时候,函数体代码并不会执行,这个函数仅仅是返回一个生成器而已

>>> def createGenerator():
...     print('head')
...     for i in range(5):
...         yield i*i
...     print('tail')
...
>>> createGenerator()
<generator object createGenerator at 0x0000023454FB5990>

当你第一次向后迭代(用nextfor...in...语句时)这个生成器时,函数体才会从最开始执行到yield处而后返回yield的值,随后再次向后迭代,会执行剩余的代码而后再次遇到yield中止并返回值。直到运行到函数结尾处中止,此时若是是用next()则会抛出StopIteration异常,若是是用for...in...则会结束循环而且不会有异常

>>> def createGenerator():
...     print('head')
...     for i in range(5):
...         yield i*i
...     print('tail')
...
>>> g = createGenerator()
>>> next(g)
head
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
tail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
相关文章
相关标签/搜索