zoukankan      html  css  js  c++  java
  • 递归和生成器函数

    递归

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

    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) 
    0
    1
    2
    

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

    In [54]: def fn1():
                    ret =1
                    index=1
                    while True:
                        yield ret
                        index += 1
                        ret *= index
    
    In [55]: g1=fn1()
    
    In [56]: next(g1)
    Out[56]: 1
    
    In [57]: next(g1)
    Out[57]: 2
    
    In [58]: next(g1)
    Out[58]: 6
    
    In [59]: next(g1)
    Out[59]: 24
    
    In [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]: 120
    
    In [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) 
    1
    2
    3
    4
    5
    7
    9
    

    在Python3 中使用:

    In [5]: def gen1(lst):
       ...:     yield from lst
    
    In [6]: g1=gen1(lst)
    
    In [7]: for j in g1:
       ...:     print(j)
    1
    2
    3
    4
    5
    7
    9
    
  • 相关阅读:
    LeetCode 453 Minimum Moves to Equal Array Elements
    LeetCode 112 Path Sum
    LeetCode 437 Path Sum III
    LeetCode 263 Ugly Number
    Solutions and Summay for Linked List Naive and Easy Questions
    AWS–Sysops notes
    Linked List
    All About Linked List
    datatable fix error–Invalid JSON response
    [转]反编译c#的相关问题
  • 原文地址:https://www.cnblogs.com/cuchadanfan/p/5926080.html
Copyright © 2011-2022 走看看