zoukankan      html  css  js  c++  java
  • python之路day14--嵌套函数、匿名函数、高阶函数。函数的递归

     

    嵌套函数

    函数里不仅可以写代码,还可以嵌套函数

    name = "小猿圈"
    
    
    def change():
        name = "小猿圈,自学编程"
    
        def change2():
            # global name  如果声明了这句,下面的name改的是最外层的全局变层
            name = "小猿圈,自学编程不要钱" #这句注释掉的话,下面name打印的是哪个值?
            print("第3层打印", name) 
    
        change2()  # 调用内层函数
        print("第2层打印", name)
    
    
    change()
    
    print("最外层打印", name)

    输出

    第3层打印 小猿圈,自学编程不要钱
    第2层打印 小猿圈,自学编程
    最外层打印 小猿圈
    

    通过上面的例子,我们理解了,每个函数里的变量是互相独立的,变量的查找顺序也是从当前层依次往上层找。

    问个哲学问题,这东西有什么用呢?哈,现在没用,不解释,长大后学了装饰器你就知道有啥用了。

    匿名函数

    匿名函数就是不需要显式的指定函数名

    #这段代码
    def calc(x,y):
        return x**y
    
    print(calc(2,5))
    
    #换成匿名函数
    calc = lambda x,y:x**y
    print(calc(2,5))
    

    你也许会说,用上这个东西没感觉有毛方便呀, 。。。。呵呵,如果是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,如下

    res = map(lambda x:x**2,[1,5,7,4,8])
    for i in res:
        print(i)
    

    输出

    1
    25
    49
    16
    64
    

    高阶函数

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

    def get_abs(n):
        if n < 0 :
            n = int(str(n).strip("-"))
        return n
    
    def add(x,y,f):
        return f(x) + f(y)
    
    
    res = add(3,-6,get_abs)
    
    print(res)

    只需满足以下任意一个条件,即是高阶函数

    • 接受一个或多个函数作为输入
    • return 返回另外一个函数

    函数的递归

     

    求100不断除以2直到商为0为止,打印每次除的商

    用循环实现

    n = 100
    while n > 0:
        n = int(n/2)
        print(n)
    
    

    输出:

    50
    25
    12
    6
    3
    1
    0

    如果用函数,如何实现呢? 

    def calc(n):
    
        n = int(n/2)
        print(n)
        if n > 0:
            calc(n) #调用自己
    
    
    calc(100)

    在函数内部,可以调用其他函数。如果一个函数在内部调用自已本身,这个函数就叫做递归函数。上面我们写的这个代码就是递归

    递归的执行过程

    def calc(n):
    
        n = int(n/2)
        print(n)
        if n > 0:
             calc(n)
        print(n) 
    
    
    calc(10)
    

    输出:

    5
    2
    1
    0
    0
    1
    2
    5
    为什么输出是这样呢? 

    如上图所示,函数在每进入下一层的时候,当前层的函数并未结束,它必须等它调用的下一层函数执行结束返回后才能继续往下走。 所以最下面的那句print(n)会等最里层的函数执行时才会执行,然后不断往外退层,所以会出现0、1、2、5的效果

    递归特性:

    1. 必须有一个明确的结束条件
    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

    递归在特定场景下还是挺有用的,以后学的一些算法就得用到递归,比如堆排、快排等,现在看还是有些复杂的,以后再讲。

    练习题

    用递归实现2分查找的算法,以从列表 a = [1,3,4,6,7,8,9,11,15,17,19,21,22,25,29,33,38,69,107] 查找指定的值。

  • 相关阅读:
    【字符串/广搜】P1032 字串变换
    【动态规划】P1541 乌龟棋
    【动态规划/递归】(团队内部比赛试题)T134293 T2.货币系统问题
    Redis-事务
    Redis-Pipeline
    Redis-通过前缀获取所有key
    Spring 三级缓存
    TopK_LRU_归并

    如何从一亿个数组里找出最大的十个
  • 原文地址:https://www.cnblogs.com/hanfe1/p/10837348.html
Copyright © 2011-2022 走看看