Python生成器之yield详解
作者:程序员喵大人
yield
为了搞清楚 yield 和 return 这两者的区别,我们先来看一个简单的例子:
>>> def self_return(n): ... print('rocky') ... while n > 0: ... print('before return') ... return n ... n -= 1 ... print('after return') ... >>> s = self_return(3) rocky before return >>> s 3
从上面的例子中函数 self_return(n) 被调用的过程中我们可以清晰的看出,s = self_return(3) 函数体内的语句就开始执行了,遇到 return 以后将值返回,并结束在函数体内的执行,所以我们看到的结果是 return 后面的语句根本没有执行,这个是 return 的特点,不知道你还记得么?如果不记得的话可以去翻我前面的文章。
下面我们来将 return 换乘 yield ,再来试试看:
>>> def self_yield(n): ... print('rocky') ... while n > 0: ... print('before yield') ... yield n ... n -= 1 ... print('after yield') ... >>> s = self_yield(3) >>> s.__next__() rocky before yield 3
仔细观察上面的例子你会发现,s = self_yield(n) 并没有去执行函数体内的语句,且 s.next() 的时候遇到 yield 的时候,会返回值,并且暂停。我们接着再继续来试一下:
>>> s.__next__() after yield before yield 2 >>> s.__next__() after yield before yield 1 >>> s.__next__() after yield Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
通过上面的继续操作,我们可以看到每次遇到 yield 的时候都会返回值,并且暂停,下次再执行的时候是从上次暂停的位置开始又继续执行的,当没有满足条件的值,就会抛出异常。
结合上面的分析和对用例的执行结果,相信你已经你已经理解了 yield 的特点,也知道它与 return 之间的区别了:一般的函数,都是止于 return;作为生成器的函数,因为有了 yield,则遇到它会挂起。
下面我想再用一个例子来具体的阐述一下。斐波那契数列相信你们已经不陌生了,我在前面的文章中不止一次的提过它,这次我们尝试将 yield 应用到斐波那契数列中:
def fibs(max): """ fibonacci sequence generator """ n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n += 1 if __name__ == "__main__": f = fibs(9) for i in f: print(i,end = ' ')
上述代码的运行结果如下:
1 1 2 3 5 8 13 21 34 55
你看,用生成器生成的斐波那契数列是不是跟以前的不一样了呢?如果有兴趣的话,你可以将我在前面文章中演示过的斐波那契数列的实现方式和现在的做一下对比,然后仔细观察一下差异之处。
经过这几次的各种演示,其实已经很明确了:在一个函数中如果有了 yield 语句,那么它就是生成器,即也是迭代器。这种方式比前面写迭代器的类要简便的多,但这不是说迭代器不好,无论是使用迭代器还是生成器都要具体问题具体分析。
到此这篇关于Python生成器之yield详解的文章就介绍到这了,更多相关Python yield内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!