python之yield表达式学习,pythonyield表达式


python中有一个略微奇怪的表达式叫yield expression,本文就来探究一下这是个什么东西。一步一步来。

iterable

复制代码 代码如下:

mylist = [1,2,3]
for item in mylist:
    print str(item)

mylist是一个列表(list),我们可以逐条取出每一个item,这个过程叫做iteration。像list这样可以用”for…in…”依次遍历的对象被称为iterable,其他的iterable还有string、tuple、dict等。iterable的一个特点是所有的item会存储到内存中,这样会产生一些不便和不利的地方,于是催生了generator(后面讲到)。

list comprehension(列表推导式)

复制代码 代码如下:

mylist = [x*x for x in range(3)]

表达式右边是一个for循环的简写形式,用[]包裹起来(称为list comprehension),表达式的值是一个list,我们可以像普通list那样使用”for…in…”遍历其元素,如:
复制代码 代码如下:

for item in mylist:
    print str(item)
generator

generator

对上面的list comprehension稍作修改:

复制代码 代码如下:

mygenerator = (x*x for x in range(3))
for item in mygenerator:
    print item

可以看到只是把[]换成了(),这时表达式的值不再是list,而是一个generator。

generator也属于iterable,但是其调用方式非常特别。

yield

复制代码 代码如下:

def creatGenerator():
    mylist = range(3)
    for x in mylist:
        yield x*x
       
mygenerator = creatGenerator()

for x in mygenerator:
    print(x)


yield的使用方法和return是一样的。但是(重点来了):


python中yield的用法问题

yield就是保存当前程序执行状态。
你用for循环的时候,每次取一个元素的时候就会计算一次。
用yield的函数叫generator,和iterator一样,它的好处是不用一次计算所有元素,而是用一次算一次,可以节省很多空间。generator每次计算需要上一次计算结果,所以用yield,否则一return,上次计算结果就没了。
所以保存列表的说法是完全错误的。
 

初学python,想问些对于yield等等的问题

关于yield,楼下kanchi240说的完全正确。我就不补充了。

想说的是。你这个用yield的函数的逻辑可能存在问题。入口参数nested是一个数组,函数里for sublist in nested被执行的时候,如果nested被改变就不合理,会产生一个异常,也许你设计的初衷就是如此。
def flatten(nested): try: for sublist in nested: for element in flatten(sublist): yield element except TypeError : yield nestedif __name__=="__main__": for x in flatten(nested=[1,[2,[3]]]): print x,type(x)输出结果是
1 <type 'int'>
2 <type 'int'>
3 <type 'int'>
你这个好象又是递归函数。分解一下步骤是这样子。
flatten(nested=[1,[2,[3]]])
sublist=1
for element in flatten(sublist):此处在子调用异常,输出1, 但是它被递归函数的循环再次yield。
下面依次类推。

我把程序修改了一下,可能看起来更清晰。
def flatten(nested,level=0): try: for sublist in nested: print "sublist:",sublist,type(sublist) for element in flatten(sublist,level+1): print level,"yield",element yield element except TypeError : print level,'yield type error',nested,type(nested) yield nestedif __name__=="__main__": for x in flatten(nested=[1,[2,[3]]]): print x,type(x)输出结果是
sublist: 1 <type 'int'>1 yield type error 1 <type 'int'>0 yield 11 <type 'int'>sublist: [2, [3]] <type 'list'>sublist: 2 <type 'int'>2 yield type error 2 <type 'int'>1 yield 20 yield 22 <type 'int'>sublist: [......余下全文>>
 

评论关闭