一、嵌套函数

  1、嵌套函数简单的理解可以看作是在函数的内部再定义函数,实现函数的“私有”。

  2、特点:

      <1> 函数内部可以再次定义函数。

      <2> 只有被调用时才会执行(外部函数被调用后,被嵌套函数调用才有效)。

  3、实例如下:

  1. #!/usr/bin/env python3
  2. #-*- coding:utf-8 -*-
  3.  
  4. def func1():
  5. print('hello world!')
  6. def func2():
  7. print('everyone...')
  8.  
  9. func1() # 输出:hello world! ,此时func2未被调用并不执行

  4、然而嵌套函数并一定就是长这样,不信,继续往下看...

    为了更直观,我直接放出几种情形的案例,如下:

  1. #!/usr/bin/env python3
  2. #-*- coding:utf-8 -*-
  3.  
  4. #情形1
  5. name = 'cc'
  6. def func1():
  7. name = 'sc'
  8. print(name)
  9. def func2():
  10. #name = 'df'
  11. print(name)
  12. func2()
  13. func1() #输出:sc df,当第10行被注释时,输出:sc sc,
  14. # 嵌套函数中的变量层层调用,当前函数中没有便向上一级函数查找
  15.  
  16. #情形2
  17. age = 21
  18. def func1():
  19. def func2():
  20. print(age) #输出:18,当前函数中并没有定义(‘第二层局部变量’)age,向第一层找
  21. age = 18 #与func2位于同一层,‘第一层局部变量’
  22. func2()
  23. print(func1(),age) #输出:None ,21,此时,函数外输出的age只能是全局变量
  24.  
  25. #情形3
  26. age = 21
  27. def func1():
  28. def func2():
  29. print(age)
  30. func2()
  31. #age = 18
  32. func1() #当31行不被注释时,运行会报错,打印age时会混淆全局age和局部age
  33. #当31行被注释时,输出: 21,此时func2调用全局age
  34.  
  35. #情形4
  36. age = 21
  37. def func1():
  38. global age #声明全局变量
  39. def func2():
  40. print('func2中的:',age) #输出>>func2中的: 21, age此时引用的是36行的全局变量
  41. func2()
  42. age = 18 #由于已经声明age是全局变量,所以此处的重新赋值就是对全局修改
  43. func1()
  44. print('全局中的:',age) #输出>>全局中的: 18, 变量age在函数func1中被修改
  45.  
  46. #情形5
  47. age = 21
  48. def func1():
  49. global age
  50. def func2():
  51. print('func4中的:',age) #输出>>func2中的: 18, age此时引用的是47行的全局变量
  52. age = 18 #由于已经声明age是全局变量,所以此处的重新赋值就是对全局修改
  53. func2()
  54. func1()
  55. print('全局中的:',age) #输出>>全局中的: 18, 变量age在函数func1中被修改
  1. '''
    情形4和情形5的区别在于age变量的修改在程序中的执行顺序,在func2调用前还是在func2调用之后,
    如果是在func2调用前修改age,则func2中输出的则是修改后的;如果是在func2调用后修改age,则func2中
    输出的就是未修改时的全局变量age,所以两者func2函数中输出的age值不同,但最后的全局输出相同。
    '''
  1.  

二、递归函数

  1、定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

  2、实例:  

  1. def calc(n):
  2. n = n // 2
  3. print(n) # 输出:9 4 2 1 0 0 0 .... //到1000层结束调用
  4. calc(n) # 重复调用自身
  5.  
  6. calc(19)

   查看默认调用层次的方法:

  1. # -*-coding:utf-8 -*-
  2. import sys
  3.  
  4. print(sys.getrecursionlimit()) #查看递归默认限制层数,默认是1000

  3、递归调用的过程

  1. #递归的执行过程
  2. def func_re(n):
  3. n = n // 2 # 地板除,商保留整数
  4. print(n)
  5. if n > 0:
  6. func_re(n)
  7. print(n)
  8. func_re(13)
  9. '''
  10. python中递归执行的逻辑是一层层调用,再一层层退出,可通过调试断点查看
  11. 6
  12. 3
  13. 1
  14. 0
  15. 0
  16. 1
  17. 3
  18. 6
  19. '''

  4、到这里,我们可以总结下递归的特性了:

    <1> 必须要有明确的终止条件

    <2> 每进入更深一层递归时,问题规模相比上次都应有所减少

    <3> 递归效率不高,层次过多会导致栈溢出

  5、了解了递归调用的过程,那么如果我不想它一直调用下去,而是满足某一条件就返回,不再执行了呢?该怎么做呢?

    实例如下:

  1. def calc(n,count):
  2. '''
  3. :param n: 需要进行递归的对象
  4. :param count: 计数器
  5. :return: 条件不成立时,返回最终值
  6. '''
  7. print(n,count)
  8. if count < 5: #运行第五次时退出
  9. return calc(n//2,count+1) #每一层接收它下一层的值,return必不可少,否则倒数第三层无法接收倒数第二层的返回值
  10. else:
  11. return n # 最终结果返回到倒数第二层(即上一个return),只执行一次
  12. func = calc(199,1)
  13. print('res运算第五次时的结果:',func) # 输出>>res运算第五次时的结果: 12.4375

    当然,递归的用处不止于此,二分查找就是递归很好的应用:

  1. data1 = [1,23,43,54,654,4544,34523]
  2. def search(data1,find_num):
  3. print(data1)
  4. if len(data1) > 1:
  5. middle = len(data1)//2
  6. if data1[middle] == find_num:
  7. print('找到了',data1[middle])
  8. elif data1[middle]>find_num:
  9. print('要找的数在%s左边'%data1[middle])
  10. return search(data1[middle],find_num)
  11. else:
  12. print('要找的数在%s右边'%data1[middle])
  13. return search(data1[middle], find_num)
  14. else:
  15. if data1[0] == find_num:
  16. print('找到了',data1[0])
  17. else:
  18. print('你要找的数不在列表中')
  19. search(data1,54)

三、高阶函数

  1、定义:变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,

  1.        这种函数称之为高阶函数。
  2.  
  3.   2、满足高阶函数的条件(任意一个):
        <1> 接受一个或多个函数作为输入
        <2> return 返回另外一个函数
     3、实例如下:
  1. #!/usr/bin/env python3
  2. #-*- coding:utf-8 -*-
  3.  
  4. # 接受一个或多个函数作为输入
  5. def func(a,b):
  6. return a-b
  7.  
  8. def func2(x):
  9. return x
  10.  
  11. f = func2(func)
  12. print(f(5,2)) #
  13.  
  14. # reyurn 返回另外一个函数
  15. def func3(a,b):
  16. return abs,a,b # abs为内置方法
  17.  
  18. res = func3(3,-5)
  19. print(res) # 输出:(<built-in function abs>, 3,-5),一个元组
  20. print(res[0](res[1]+res[2])) #输出:2
  1.  
  1.  

  

Python嵌套、递归、高阶函数的更多相关文章

  1. Python入门篇-高阶函数

    Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数  1>.First Class Object 函数在Python中是一等公民 函数也 ...

  2. Python 函数式编程 & Python中的高阶函数map reduce filter 和sorted

    1. 函数式编程 1)概念 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念.wiki 我们知道,对象是面向对象的第一型,那么函数式编程也是一样,函数是函数 ...

  3. Python中的高阶函数与匿名函数

    Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...

  4. 嵌套&匿名&高阶函数

    嵌套&匿名&高阶函数 嵌套函数 函数可以嵌套定义并调用函数 name = "小明" def change(): name = "小明,你好" d ...

  5. 匿名函数python内置高阶函数以及递归

    匿名函数 python定义一个函数通常使用def关键词,后面跟函数名,然后是注释.代码块等. def func(): '''注释''' print('from func') 这样就在全局命名空间定义了 ...

  6. python字符串反转 高阶函数 @property与sorted(八)

    (1)字符串反转 1倒序输出 s = 'abcde' print(s[::-1]) #输出: 'edcba' 2 列表reverse()操作 s = 'abcde' lt = list(s) lt.r ...

  7. Python学习笔记 - 高阶函数

    高阶函数英文叫Higher-order function.什么是高阶函数?我们以实际代码为例子,一步一步深入概念. 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下 ...

  8. 14 python初学(高阶函数 递归函数 内置函数)

    高阶函数:1.  函数名是一个变量,函数名可以进行赋值 2. 函数名可以作为函数参数,还可以作为函数返回值(函数名称作为函数返回值时返回的是:函数的地址:print 这个返回值的调用相当于执行这个函数 ...

  9. python 常用的高阶函数

    前言 高阶函数指的是能接收函数作为参数的函数或类:python中有一些内置的高阶函数,在某些场合使用可以提高代码的效率. map() map函数可以把一个迭代对象转换成另一个可迭代对象,不过在pyth ...

  10. python学习笔记——高阶函数map()

    满足以下两点中任意一点,即为高阶函数: 1.函数接收一个或多个函数作为参数 2.函数返回一个函数 1 描述 用函数和可迭代对象中每一个元素作为参数,计算出新的迭代对象 map() 会根据提供的函数对指 ...

随机推荐

  1. React Native探索(四)Flexbox布局详解

    相关文章 React Native探索系列 前言 在Android开发中我们有很多种布局,比如LinearLayout和RelativeLayout,同样在React Native也有它的布局,这个布 ...

  2. 无法打开包括文件:“iostream.h”

    把#include<iostream.h>改为:#include<iostream>using namespace std; #include<iostream.h> ...

  3. DevExpress使用笔记

    DevExpress这套控件用了也有几年的时间了,现在用的版本是14.2.2. 确实是很强大的一套控件,用的好,做出的效果也是相当的好,记录一些平常用到的代码,就当记笔记吧,慢慢完善,其实网上也有大把 ...

  4. [转载] 视音频数据处理入门:RGB、YUV像素数据处理

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  5. linux C使用strerror来追查错误信息

    最近工作中有个需求:程序将文件进行处理,然后将处理完毕的文件挪走.我用了rename函数来挪动文件,可是在docker化的环境中,文件却无法挪动.不知道什么原因.现在,对程序进行调整,如果rename ...

  6. NOIP模拟题 管道

    题目大意 给定$n$个点的无向图,求它的$Dfs$序方案数$n\leq 18$ 题解 状压$Dp+$记忆化搜索. 设$F_{i,now}$表示到达$i$其中$now$集合代表的点集已经遍历过,还需要遍 ...

  7. MAC OS X常用命令总结2

    1. dir:显示某个目录下的子目录与文件. 格式:dir [x:] [Path] [filename][ parameter] 参数解释: /a      显示所有文件夹与文件. /p     分页 ...

  8. c#和c++互操作(平台调用相关)

    [DllImport("ScreenCaptureLib.dll", CallingConvention = CallingConvention.Cdecl)] public st ...

  9. Linux下搭建 NFS

    一.NFS简介 NFS是Network File System的缩写,即网络文件系统.一种使用于分散式文件协定,有SUN公司开发.功能是通过网络让不同的机器.不同的操作系统能够分享个人数据,让应用程序 ...

  10. spark-shell与scala生成parquet文件

    spark-shell用户 spark-shell只能spark用户来进行初始化,如果用hdfs或者root将会卡在spark-shell的初始化那个地方.可以用这两个用户来验证spark安装时成功地 ...