Python有两类特殊函数:匿名函数和递归函数。
匿名函数是指没有函数名的简单函数,只可以包含一个表达式,不允许包含其他复杂的语句,表达式的结果是函数的返回值。
递归函数是指直接或间接调用函数本身的函数。递归函数反映了一种逻辑思想,用它解决某些问题时显得很简练。
1.匿名函数
lambda函数的定义和调用示例。
f=lambda a,b=2,c=5: a-b+c #使用默认值参数
print("f=",f(10,20)) #输出: f=-5
print("f=",f(10,20,30)) #输出:f=20
print("f=",f(c=20,a=10,b=30)) #使用关键字实参,输出:f=0
f=lambda n,m:sum([k**m for k in range(1,n+1)])
s=f(100,1)+f(50,2)+f(10,-1)
print("s=%10.4f"%(s))#占位宽度10,保留4位小数的浮点数
2.递归函数
递归函数是指一个函数的函数体中又直接或间接地调用该函数本身的函数。
如果函数a中又调用函数a本身,则称函数a为直接递归。
如果函数a中先调用函数b,函数b中又调用函数a,则称函数a为间接递归。
程序设计中常用的是直接递归。
n=int(input("请输入n的值:"))
def fac(n):
if n<=1: return 1
else: return n*fac(n-1)
m=fac(n) #调用函数
print("%d!=%5d"%(n,m))
编写递归程序要注意两点:一要找出正确的递归算法,这是编写递归程序的基础;而要确定算法的递归结束条件,这是决定递归程序能否正常结束的关键。
用递归方法计算下列多项式函数的值。
x,n=eval(input("请输入x和n的值:"))
def p(x,n):
if n==1: return x
else: return x*(1-p(x,n-1))
v=p(x,n) #调用函数
print("p(%d,%d)=%d"%(x,n,v))
当一个问题蕴含了递归关系且结构比较复杂时,采用递归函数可以使程序变得简洁、紧凑,能够很容易地解决一些用非递归算法很难解决的问题。
但递归算法是以牺牲存储空间为代价的,因为每一次递归调用都要保存相关的参数和变量。
而且递归函数也会影响程序执行速度,由于反复调用函数,会增加时间开销。
导入模块随着程序的变大及代码的增多,为了更好地维护程序,一般会把代码进行分类,分别放在不同的文件中。
公共类、函数都可以放在独立的文件中,这样其他多个程序都可以使用,而不必把这些公共的类、函数等在每个程序中复制一份,这样独立的文件就叫做模块。
标准库中有与时间相关的time、datetime模块,随机数的random模块,与操作系统交互的os模块,对Python解释器相关操作的sys模块,数学计算的math模块等几十个模块。要查看所有模块,可以使用命令
help("modules")
要看math模块的帮助,可以使用命令
import math; help(math)
要看math模块的所有函数,可以使用命令
import math; dir(math)
导入模块有四种方式:
1.import 模块名 [as 别名]
使用这种方式导入以后,使用时需要在对象之前加上模块名作为前缀,即必须以“模块名.对象名”的形式进行访问。
如果模块名字很长的话,可以为导入的模块设置一个别名,然后使用“别名.对象名”的方式来使用其中的对象。
import numpy as np #导入numpy库,相当于大模块,并设置别名为np
import numpy.linalg as LA #导入numpy库下linalg(线性代数)模块,别名为LA
a=np.linspace(0,10,5) #产生0到10之间等间距的5个数
b=LA.norm(a) #求b的模,即向量a的长度
print(a)
print("a的长度为:%7.4f"%b)
同时导入的模块有多个时,模块名字之间用逗号分隔
import time, random #导入基础库中的time和random模块
2.from 模块名 import 对象名 [as 别名]
使用这种方式仅导入明确指定的对象,并且可以为导入的对象确定一个别名。
这种导入方式可以减少查询次数,提高访问速度;同时也可以减少程序员需要输入的代码量,因为不需要使用模块名作为前缀。
from numpy import random as rd #从numpy库中导入模块random并设置别名为rd
from math import sin, cos #导入模块中的正弦函数和余弦函数
from random import randint #说明:因randint()函数属于random模块,必须在函数名称之前先加上random,告诉Python在random模块中寻找这个函数。
#randint 产生的随机数区间是包含左右极限的,也就是说左右都是闭区间的[1, n],能取到1和n。而 randrange 产生的随机数区间只包含左极限,
#也就是左闭右开的[1, n),1能取到,而n取不到。randint 产生的随机数是在指定的某个区间内的一个值,
#而 randrange 产生的随机数可以设定一个步长,也就是一个间隔。
a=rd.randint(0,10,(1,3)) #产生[0,10)的3个元素的随机整数数组
#这里为什么会导致取不到10呢,这是因为一旦randint取值为范围值时,该函数作用如同randrange,导致无法取到尾数
b=randint(0,10) #产生[0,10]上的一个随机整数,不能产生向量
print("sin(b)=%6.4f"%sin(b))
print("cos(b)=%6.4f"%cos(b))
b#是直接使用python中randint函数而a使用的是random模块下的randint
注意import random和import numpy.random的差别,
import random是导入Python基础库的random模块,
import numpy.random是导入numpy库的random模块,¶
建议以后使用函数时,尽量使用numpy库中的函数,
它的函数可以对向量进行运算,而基础库中的函数一般对标量进行运算。
基础库中的random.randint()函数无法产生向量,
numpy库中的numpy.random.randint()函数可以产生向量。
3.from 模块名 import *
这是第2种用法的一种极端情况,可以一次导入模块中通过_ all _变量指定的所有对象。
使用这种一次导入库或模块中所有对象的方式固然简单省事,但是并不推荐使用,一旦多个模块中有同名的对象,这种方式将会导致混乱。
建议使用什么函数就导入什么函数。
分析:定义一个匿名函数求累加项,循环控制累加100次。
from math import log, exp, sin, pi
f=lambda n:(1+log(n)+sin(n))/(2*pi)
y=exp(2)
for n in range(1,101): y += f(n)#上一个y加f(2)
print("y=%7.4f"%y)
log()函数如math.log(math.e)返回1.0,math.log(100,10)返回2.0
单个参数就是lnx函数,双参数即是log函数
exp()函数返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
注 Python的帮助和MATLAB的帮助是类似,看numpy库的模块和帮助信息,使用命令:
import numpy help(numpy)
help("numpy")
该处有两种解决方案
1.不改变原配置文件jupyter_notebook_config.py中的c.NotebookApp.iopub_data_rate_limit 参数
(在不编辑Notebookapp配置的情况下加载大文件)
使用jupyter notebook --NotebookApp.iopub_data_rate_limit=2147483647 加上你变成文件的路径
2.改变原配置文件jupyter_notebook_config.py中的c.NotebookApp.iopub_data_rate_limit 参数
找到jupyter_notebook_config.py文件改变源码为c.NotebookApp.iopub_data_rate_limit = 2147483647
也就是说去掉注释号#并增大数值
看numpy库中random模块的帮助使用命令:
help(numpy.random)
help("numpy.random")
可以看到numpy.random模块中所有对象的信息。
如果只看numpy.random模块中的函数名使用命令dir(“numpy.random”)。
dir("numpy.random")
4.自定义模块的导入
通常用户将多个函数收集在一个脚本文件中,创建一个用户自定义的Python模块。
在pycharm中新建FunctionSet.py文件
def f(x): return x**2+x+1 def g(x): return x**3+2*x+1 def h(x): return 1/f(x)
第一种调用模式:
import FunctionSet as fs print(fs.f(1),'t',fs.g(2),'t',fs.h(3))
第二种调用模式:
from FunctionSet import f, g, h print(f(1),'t',g(2),'t',h(3))



