首页 > 代码库 > 递归和生成器函数

递归和生成器函数

递归

如果函数包含了对其自身的调用,该函数就是递归。递归广泛应用于语言识别和使用递归函数的数学应用中。例如:斐波那契数列和求阶乘等。下面就上面两种使用举例:
斐波那契数列:

In [12]: def fib(n):                if n==0:                    return 1                if n==1:                    return 1                return fib(n-2)+fib(n-1)In [18]: fib(10)Out[18]: 89

阶乘:

In [19]: def fn(n):   ....:     if n==0:   ....:         return 1   ....:     if n==1:   ....:         return 1   ....:     return n*fn(n-1)In [20]: fn(10)Out[20]: 3628800

由于递归总是涉及到压栈和出栈,所以递归函数在Python中非常慢,并且有深度限制,所以尽量避免使用递归。在Python中递归的限制可以通过 sys.getrecursionlimit() 得到深度限制,通过sys.setrecursionlimit调整递归深度限制。
注意:循环都可以转化为递归,但不是所有递归都可以转化为循环。

生成器函数

生成器函数是一个带yield语句的函数。一个函数或者子程序只能返回一次,但一个生成器能暂停执行并返回一个中间的结果,这就是yield的功能,返回一个值给调用者并暂停执行。当生成器被next()方法调用的时候,它会准确的从离开地方继续。
请注意yield和return的区别:

  • yield 弹出值,暂停函数

  • return返回值, 并且结束函数

  • 当yield和return同时存在时, return的返回值会被忽略,但是return依然可以中断生成器

In [50]: def gen(x):   ....:     for i in range(10):   ....:         if i ==3:   ....:             return i   ....:         yield i   In [51]: g = gen(10)In [52]: for i in g:   ....:     print(i) 012

注意:可以使用生成器来替换递归,同时所有的递归,都可以用生成器替换。

In [54]: def fn1():                ret =1                index=1                while True:                    yield ret                    index += 1                    ret *= indexIn [55]: g1=fn1()In [56]: next(g1)Out[56]: 1In [57]: next(g1)Out[57]: 2In [58]: next(g1)Out[58]: 6In [59]: next(g1)Out[59]: 24In [60]: next(g1)Out[60]: 120
def g(n):    def factorial():        ret = 1        idx = 1        while True:            yield ret            idx += 1            ret *= idx    gen = factorial()    for _ in range(n-1):        next(gen)    return next(gen)In [63]: fn2(5)Out[63]: 120In [64]: fn2(6)Out[64]: 720

生成器函数的列表传参
在Python2 中使用:

In [1]: lst = [1,2,3,4,5,7,9]In [2]: def gen(lst):   ...:     for x in lst:   ...:         yield x        In [3]: g=gen(lst)In [4]: for i in g:   ...:     print(i) 1234579

在Python3 中使用:

In [5]: def gen1(lst):   ...:     yield from lstIn [6]: g1=gen1(lst)In [7]: for j in g1:   ...:     print(j)1234579

递归和生成器函数