函数,递归函数,返回值作用域,插入排序
2021-07-13 16:06
标签:可变 dep tuple 构建 cal 实现 limit 深度 可变参数 def语句定义函数 参数调用时传入的参数要和定义的个数相匹配(可变参数例外) 参数默认值(缺省值) 可变参数 编写一个函数,接受一个参数n,n为正整数,左右两种打印方式。要求数字必须对齐 函数的返回值 函数嵌套 变量名解析原则LEGB 插入排序 匿名函数 匿名函数 递归Recursion 递归的性能 递归总结 函数,递归函数,返回值作用域,插入排序 标签:可变 dep tuple 构建 cal 实现 limit 深度 可变参数 原文地址:http://blog.51cto.com/13896223/2164849
数学定义:y=f(x) ,y是x的函数,x是自变量。y=f(x0, x1, ..., xn)
Python函数
由若干语句组成的语句块、函数名称、参数列表构成,它是组织代码的最小单元完成一定的功能
函数的作用
结构化编程对代码的最基本的封装,一般按照功能组织一段代码封装的目的为了复用,减少冗余代码代码更加简洁美观、可读易懂
函数的分类
内建函数,如max()、reversed()等库函数,如math.ceil()等
def 函数名(参数列表):
函数体(代码块)
[return 返回值]
函数名就是标识符,命名要求一样语句块必须缩进,约定4个空格Python的函数没有return语句,隐式会返回一个None值定义中的参数列表成为形式参数,只是一种符号表达,简称形参
调用
函数定义,只是声明了一个函数,它不会被执行,需要调用调用的方式,就是函数名加上小括号,括号内写上参数调用时写的参数是实际参数,是实实在在传入的值,简称实参
位置参数
def f(x, y, z) 调用使用 f(1, 3, 5)按照参数定义顺序传入实参
关键字参数
def f(x, y, z) 调用使用 f(x=1, y=3, z=5),使用形参的名字来出入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同
传参
f(z=None, y=10, x=[1])
f((1,), z=6, y=4.1)
f(y=5, z=6, 2) #
要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的
定义时,在形参后跟上一个值
def add(x=4, y=5):
return x+y
测试调用 add(6, 10) 、add(6, y=7) 、add(x=5) 、add()、add(y=7)、 add(x=5, 6) 、add(y=8,
4)、add(x=5, y=6)、add(y=5, x=6)
测试定义后面这样的函数 def add(x=4,y)
作用
参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值
参数非常多的时候,并不需要用户每次都输入所有的参数,简化函数调用
举例
定义一个函数login,参数名称为host、port、username、password
一个形参可以匹配任意个参数
位置参数的可变参数
有多个数,需要累加求和
在形参前使用*表示该形参是可变参数,可以接收多个实参
收集多个实参为一个tuple
关键字参数的可变参数
形参前使用*符号,表示可以接收多个关
可变参数混合使用
总结
有位置可变参数和关键字可变参数
位置可变参数在形参前使用一个星号
关键字可变参数在形参前使用两个星号**
位置可变参数和关键字可变参数都可以收集若干个实参,位置可变参数收集形成一个tuple,关
键字可变参数收集形成一个dict
混合使用参数的时候,可变参数要放到参数列表的最后,普通参数需要放到参数列表前面,位
置可变参数需要在关键字可变参数之前
keyword-only参数(Python3加入)
如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通的
参数了,而是keyword-only参数
Python函数使用return语句返回“返回值”
所有函数都有返回值,如果没有return语句,隐式调用return None
return 语句并不一定是函数的语句块的最后一条语句
一个函数可以存在多个return语句,但是只有一条可以被执行。如果没有一条return语句被执
行到,隐式调用return None
如果有必要,可以显示调用return None,可以简写为return
如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其它语句就不会
被执行了
作用:结束函数调用、返回值
函数嵌套
在一个函数中定义了另外一个函数
函数有可见范围,这就是作用域的概念
内部函数不能在外部直接使用,会抛NameError异常,因为它不可见
作用域***
作用域
一个标识符的可见范围,这就是标识符的作用域。一般常说的是变量的作用域
全局作用域
在整个程序运行环境中都可见
局部作用域
在函数、类等内部可见
局部变量使用范围不能超过其所在的局部作用域
从嵌套结构例子看出
外层变量作用域在内层作用域可见
全局变量global,使用global关键字的变量
global使用原则
外部作用域变量会内部作用域可见,但也不要在这个内部的局部作用域中直接使用,因为
函数的目的就是为了封装,尽量与外界隔离
如果函数需要使用外部全局变量,请使用函数的形参传参解决
自由变量:未在本地作用域中定义的变量。例如定义在内存函数外的外层函数的作用域中的变量
闭包:就是一个概念,出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量,就形成
了闭包。
使用了nonlocal关键字,将变量标记为不在本地作用域定义,而在上级的某一级局部作用域中定义,但不
能是全局作用域中定义
Local,本地作用域、局部作用域的local命名空间。函数调用时创
建,调用结束消亡
Enclosing,Python2.2时引入了嵌套函数,实现了闭包,这个就
是嵌套函数的外部函数的命名空间
Global,全局作用域,即一个模块的命名空间。模块被import时
创建,解释器退出时消亡
Build-in,内置模块的命名空间,生命周期从python解释器启动
时创建到解释器退出时消亡。例如 print(open),print和open都
是内置的变量
所以一个名词的查找顺序就是LEGB
直接插入排序原理
在未排序序列中,构建一个子排序序列,直至全部数据排序完成
将待排序的数,插入到已经排序的序列中合适的位置
增加一个哨兵,放入待比较值,让它和后面已经排好序的序列比较,找到合适的插入点
匿名,即没有名字
匿名函数,即没有名字的函数
没有名字如何定义
没有名字如何调用
如果能调用,如何使用
使用lambda关键字来定义匿名函数
参数列表不需要小括号
冒号是用来分割参数列表和表达式的
不需要使用return,表达式的值,就是匿名函数返回值
lambda表达式(匿名函数)只能写在一行上,被称为单行函数
用途
在高阶函数传参时,使用lambda表达式,往往能简化代码
递归要求
递归一定要有退出条件,递归调用一定要执行到这个退出条件。没有退出条件的递归调用,就是无限
调用
递归调用的深度不宜过深
Python对递归调用的深度做了限制,以保护解释器
超过递归深度限制,抛出RecursionError: maxinum recursion depth exceeded 超出最大深
度
sys.getrecursionlimit()
循环稍微复杂一些,但是只要不是死循环,可以多次迭代直至算出结果
fib函数代码极简易懂,但是只能获取到最外层的函数调用,内部递归结果都是中间结果。而且给定一个n
都要进行近2n次递归,深度越深,效率越低。为了获取斐波那契数列需要外面在套一个n次的循环,效率
就更低了
递归还有深度限制,如果递归复杂,函数反复压栈,栈内存很快就溢出了
递归是一种很自然的表达,符合逻辑思维
递归相对运行效率低,每一次调用函数都要开辟栈帧
递归有深度限制,如果递归层次太深,函数反复压栈,栈内存很快就溢出了
如果是有限次数的递归,可以使用递归调用,或者使用循环代替,循环代码稍微复杂一些,但是只要不是
死循环,可以多次迭代直至算出结果
绝大多数递归,都可以使用循环实现
即使递归代码很简洁,但是能不用则不用递归
上一篇:python3学习(3)
下一篇:Python3 字典