四级考级要点
函数
函数的概念
- 函数是一段具有特定功能的、可重用的语句组
- 使用函数的主要目的是减低编程难度和代码重用
- 函数能完成特定的功能,对函数的使用不需要了解函数内部实现原理,只要了解函数的输入输出方式即可
- 函数的定义必须在主程序调用语句之前出现
定义函数
定义函数的格式如下:
def 函数名(0或多个参数):
函数体(多行代码)
说明:函数名和变量的命名规则一致
函数的使用
def user(): #def 关键字后面加函数名定义函数,定义以英文冒号结尾
print("Hello World") #函数体,用来写该函数需要完成的功能的代码
user() #使用函数名()的方式调用函数
运行结果
Hello World
形参和实参
实参(实际参数)是一个实实在在存在的参数,是实际占用内存地址的,也可以认为实参是调用函数是传递的参数;
形参(形式参数)只是意义上的一种参数,是不占用内存地址的,在函数定义时的参数。
(1)位置实参
在调用函数时,必须将每个实参都关联到函数定义中的每一个形参,最简单的关联方式就是基于实参的位置(顺序)。
def f(x,y,z): #首先在定义函数时传入3个形参x、y、z
print(x,y,z)
f(3,2,1) #在调用该函数时,通过位置实参的方式,将实参映射到形参,一一对应,即x=3,y=2,z=1
运行结果:
3 2 1
需要注意,如果使用位置实参的方式传值,传入的实参个数必须与形参相同,否则运行程序会报错。
(2)关键字实参
关键字实参是通过“关键字=值”的方式传值,就不需要考虑函数调用过程中形参的顺序。同一个参数不能传两个值。
def f(x,y,z):
print(x,y,z)
f(x=1,y=2,z=3) #通过“关键字=值”的方式,将实参与形参关联映射,不需要考虑形参的顺序,顺序也可以改变,即y=2,z=3,x=1,运行的结果不会发生改变
运行结果:
1 2 3
关键字实参,不用考虑参数的顺序,如下三种方式,传递的参数是一样的
f(x=1,y=2,z=3)
f(y=2,x=1,z=3)
f(z=3,x=1,y=2)
(3)既有位置实参,又有关键字实参
def f(x,y,z):
print(x,y,z)
f(1,y=2,z=3) #混用两种方式时,位置实参必须放在关键字实参之前,否则运行程序会报错,如1,y=2,3或者y=2,1,3都不可行
运行结果:
1 2 3
注意:位置实参必须放在关键字实参前面
(4)默认值
定义函数时,也可以指定形参的默认值,如果在调用函数时给函数提供了实参,Python将使用指定的实参值;否则将自动调用形参的默认值。因此,如果给形参指定了默认值,调用时可以不给它传值。使用默认值可以简化函数的调用。
def f(x,y=2): #定义函数时在这里给形参设置了默认值=2
print(x,y)
f(1) #在调用此函数时,只传入了一个实参,义的值就会使用默认值
运行结果:
1 2
还可以在调用时更改默认值,如下例所示。
def f(x,y=2):
print(x,y)
f(1,3) #在调用该图数时,给设置了默认值的形参立再次赋值,运行结果会使用新传入的实参值
运行结果:
1 3
在使用形参默认值时需要注意:在形参列表中必须先列出没存默认值的形参,再列出有默认值的形参。
(5)列表和字典
当不确定需要传入的值是多少时,在定义形参时,可以使用*args(列表)、**kwargs(字典)来表示。
def f(*args,**kwargs):
print(args)
print(kwargs)
f(1,2,3,4,5,y=1,z=2) #y=1,z=2作为键值对被传给kwargs
运行结果:
(1, 2, 3, 4, 5)
{'y': 1,'z': 2}
说明:
位置参数作为一个元组传递给列表参数,关键字参数作为一个字典传递给字典参数
匿名函数
格式如下:
函数名 = lambda 参数列列表 : 表达式
例如:
>>> myFun = lambda r:2*3.14*r
>>> myFun(5)
31.400000000000002
注意
lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用。
lambda表达式能接收任何数量的参数但只能返回一个表达式的值。
lambda表达式需要定义变量保存
函数的返回值
函数用return 语句将值返回调用函数的代码行,未使用return语句返回,则默认返回None。
下面是一个简单的程序,用于接收姓氏和名字,然后返回完整的人名信息。
def name(first_name,last_name):
full_name=first_name+" "+last_name
return full_name
print(name("zhangsan","san"))
运行结果:
zhangsan san
函数可以返问任何类型的值,包括字典、列表这样较复杂的数据结构。
全局变量和局部变量
一般定义在程序最开始处的变量称为全局变量,而在函数中定义的变量称为局部变量。
可以简单理解为,无缩进的为全局变量,有缩进的是局部变量。
全局变量的作用域是整个程序,而局部变量的作用域是函数内部。当程序运行时,首先会找程序内部有没有局部变量,如果有,则调用;如果没有,才去调用全局变量。
name='zhang' #全局变量
def f():
name="li" #局部变量
print(name)
f()
print(name) #打印全局变量name的值
运行结果:
li
zhang
可以通过global关键字,通过局部变量修改全局变量的值,如下例所示。
name="zhang" #定义全局变量
def f():
global name #在函数内部,通过global关键字,通过局部变量修改全局变量的值
name="li"
print(name)
f() #打印局部变量name的值
print(name) #打印全局变量name的值
运行结果:
li
li
在运行结果中可以明显看出,使用global关键字后,在定义局部变量的同时也修改了全局变量的值。
global与nonlocal的区别:
global关键字用来在定义局部变量的同时,修改全局变量的值;
nonlocal关键字用来在函数或局部作用域使用外层(非全局)变量。
递归与递推
递归
在定义一个函数或过程时,如果出现调用自身的成分,则称为递归。
递归算法的实现要点:
- 边界条件和边界值(出口)
- 递推关系(公式)
递归函数的一般写法
def f(n):
if 边界条件:
return 出口值
else:
return 递推关系
斐波那契数列
斐波那契数列指的是这样一个数列:1 、1、2、3、5、8、13、21、34......其第1项、第2项为1,从第3项开始,每一项是前两项之和。
边界条件为:f(1)=1,f(2)=1
递推关系为:f(n) = f(n-1) + f(n-2)
由以上边界条件和递推关系,可以得到如下函数:
def f(n):
if n==1 or n==2: #边界条件
return 1
else:
return f(n-1)+f(n-2) #递推关系
print(f(6))
递推
递推是序列计算中的一种常用方法。它是按照一定的规律来计算序列中的每一项,通常是通过计算前面的一些项来得出序列中指定项的值,如非常有名的斐波那契数列,python程序如下。
def f(n):
a=b=c=1
for i in range(n-2):
c=a+b
a=b
b=c
return c
print(f(6))
递归和递推算法的比较
递归算法简单易懂,但速度慢,对效率要求高的代码,不推荐使用
递推算法写起来麻烦些,但速度很快
分治算法
分治算法的概念
分:将一个复杂的问题分成两个或更多个相同或相似的子问题,再把子问题分成更小的子问题。
治:最后子问题可以简单地直接求解。
合:将所有子问题的解合并起来就是原问题的解。
分治算法的特征
(1)该问题的规模缩小到一定的程度就可以容易地解决。
(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优结构性质。
(3)该问题分解出的子问题的解可以合并为该问题的解。
(4)该问题所分解出的各个子间题是相互独立的,即子问题之间不包含公共的子子问题。
- 快速排序是典型的分治算法
算法优化
时间复杂度
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n),算法的时间度量记作T(n)=O((n)),它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长关系,称作算法的渐进时间复杂度,简称时间复杂度。
一般规律如下:
- 没有循环的算法:时间复杂度为O(1)
- 一层循环的算法:时间复杂度为O(n)
- 两层循环的算法:时间复杂度为O(n^2^)
以上只是一般情况,如下特殊情况:
i=1
n=100
while i<n:
i=i*2
量级为对数阶,2^x^=n,所以时间复杂度为O(log~2~n)。
小结∶
平均运行时间是期望的运行时间,最坏的运行时间是一种保证。我们提到的运行时间都是最坏的运行时间。
空间复杂度
空间复杂度是指算法被编写成程序后,在计算机中运行时所需存储空间大小的度量,记作S(n)=O(f(n)),其中n为问题的规模或大小。
存储空间一般包括3个部分∶
(1)输入数据所占用的存储空间;
(2)指令、常数、变量所占用的存储空间
(3)辅助(存储)空间。
算法的空间复杂度一般指的是辅助空间。
一维数组a[n]的空间复杂度为O(n)。
二维数组a[n][m]的空间复杂度为O(n*m)。
第三方库(模块)的获取、安装与调用
第三方库的获取、安装方法
安装Python第三方库的3种方法为∶
(1)使用pip命令;
(2)集成安装方法;
(3)文件安装方法。
常用的pip指令如下。
pip install <第三方库名>∶安装指定的第三方库。
pip install --upgrade <第三方库名>∶将已经安装的第三方库更新到最新版本中。
--upgrade可以简写为-U ,pip install -U <第三方库名>
pip uninstall <第三方库>∶卸载指定的第三方库。
pip download <第三方库>∶下载但不安装指定的第三方库,作为后续的安装基础。
pip show <第三方库>∶列出指定第三方库的详细信息。
pip search <第三方库>∶根据关键词在名称和介绍中搜索第三方库。
pip list∶列出当前系统已经安装的第三方库。
python -m pip install --upgrade pip∶ 升级 pip(Python 3.4之后的版本都自带了pip)。
第三方库的导入方法
1. import 模块名1 [as别名1] ,模块名2 [as别名2] ,…
使用这种语法格式的import语句,会导入指定模块中的所有成员(包括变量、函数、类等)。当需要使用模块中的成员时,只需将该模块名(或别名)作为前缀,如下例所示。
>>> import math
>>> math.pi
3.141592653589793
注意,用[]括起来的部分,可以使用,也可以省略。
>>> import math as m
>>> m.pi
3.141592653589793
2. from 模块名 import 成员名1 [as别名1] ,成员名2 [as别名2] ,…
使用这种语法格式的import语句,只会导入模块中指定的成员,而不是全部成员。同时,当程序中使用该成员时,无须附加任何前缀,直接使用成员名(或别名)即可。
from math import * #导入模块中的所有成员