函数是指被封装起来的、可重复使用的,实现某种功能的一段代码。函数的作用是提高代码的复用性、降低代码的冗余,使程序结构更加清晰。
任务1:分类统计
编写程序s7A.py,要求:
1、分别统计输入字符串中数字、大写字母、小写字母和其他字符的个数。
2、编写函数count(s,f):
(1)s为字符串,需用来分类统计各类字符的个数
(2)f为可选参数,指定字符类型。可取值:
0(数字,默认值)、1(大写字母)、2(小写字母)。
(3)函数值为s中由f指定类型的字符个数。如count("aW32")的值为2。
3、程序运行效果(依次输出数字、大写字母、小写字母和其他字符个数):
输入字符串:sw3A2SWj9k+86*
输出:5-3-4-2
"""
(1)函数默认参数(教材P69)
定义函数时,可以指定形式参数的默认值。调用函数时如果不传递值,则使用该默认值。
def fun(s,f=0): #函数定义
if f==0:
return s.lower( )
elif f==1:
return s.upper( )
else:
return s. title( )
#主程序
s="Python programming is fun"
print(fun(s)) #函数调用。f使用该默认值0
print(fun(s,1)) #函数调用。f接受实参传递值1
print(fun(s,2)) #函数调用。f接受实参传递值2
程序输出:
python programming is fun
PYTHON PROGRAMMING IS FUN
Python Programming Is Fun
主程序函数调用print(fun(s,1))语句中的s和1,是实际参数;而函数定义def fun(s,f=0)中的s和f,是形式参数。注意:所有位置参数必须出现在默认参数前。例如:def fun(f=0,s),或def fun(s,f=0,t),都是错误的。
(2)统计字符串中各类字符的个数
方法①:利用简单变量存放统计结果
s = input('输入字符串:')
a = b = c = d = 0 #abcd分别存放统计结果
for x in s: #字符串遍历
if x.isdigit( ):
a += 1
elif x.isupper( ):
b += 1
elif x.islower( ):
c += 1
else:
d += 1
print(f'{a}-{b}-{c}-{d}') #f格式化输出
程序输出:
输入字符串:sw3A2SWj9k+86*
输出:5-3-4-2
方法②:利用列表元素存放统计结果
s = input('请输入一串字符:')
r = [0, 0, 0, 0] #列表r中各元素存放统计结果
for x in s:
if ord('0') <= ord(x) <= ord('9'): #r[0]存放数字字符个数
r[0] += 1
elif ord('A') <= ord(x) <=ord( 'Z'): #r[1]存放大写字符个数
r[1] += 1
elif ord('a') <= ord(x) <= ord('z'):
r[2] += 1
else:
r[3] += 1
print(r[0], r[1], r[2], r[3], sep='-') #普通方式输出
"""可不可以采用元组r=(0,0,0,0),利用元组元素来存放统计结果??
ord( )和chr( ) 函数:(教材P73)
ord( )函数,用于返回字符在Unicode编码表中对应的码值,其参数是一个字符。chr( )和ord( )函数的功能,正好相反。
>>>ord('A') #字符'A'的ASCII码,是65
65
>>>chr(65)
'A'
方法③:利用列表元素存放中间结果
s = input('请输入一串字符:')
t = [(48, 57), (65, 90), (97, 122)] #数字大写小写字母,码值对照表
r = [ ] #列表r用来存放中间结果
for i in range(3):
b = [1 for x in s if t[i][0] <= ord(x) <= t[i][1]]
r.append(b)
a = sum(r[0])
b = sum(r[1])
c = sum(r[2])
other = len(s) - a - b - c
print(a, b, c, other, sep='-')
"""列表t是一个嵌套列表,各元素的值,t[0][0]=48,t[0][1]=57,...
推导式生成的列表r中,生成表达式是整数1。得到的列表r也是嵌套列表,内容为:[ [1, 1, 1, 1, 1], [1, 1, 1], [1, 1, 1, 1] ]。其中的[1, 1, 1, 1, 1],表示数字个数有5个;[1, 1, 1]表示,大写字母有3个。
不用sum(r[0]),用count(r[0])函数,可不可以??可以。但可能会与题目要求的函数名称冲突。
(3)函数返回值(教材P67)
通过return语句,将结果返回给函数调用者。若函数没有返回值,return语句可以省略。
① 返回单一值(简单变量或表达式)
def fun( ... ):
a=0
......
return a #返回值为简单变量a
② 返回多个值(元组方式)
def fun( ... ):
a = b = c = d = 0
......
return a,b,c,d #返回值为省略括号( )的元组
主程序调用方法:
x,y,z,k=fun( ...) #返回值直接传递给x,y,z,k等4个变量。
w=fun( ...) #赋值给元组w,再用w[0]-w[3]获取具体值
③ 返回多个值(列表方式)
def fun(s, f=0):
a=[0,0,0,0]
......
return a #返回值为列表a,包含4个元素
三种情况,本质上是一样的,return只能返回一个对象。②中的return a,b,c,d,等同于return (a,b,c,d),省略了括号的元组。③中的return a,返回的是一个列表,间接带回了多个值,类似于其他高级语言中函数的地址传递。 而①类似于其他高级语言中的值传递。
提示:
前面方法①、方法②和方法③,输入输出都是对的。但不满足题目要求。
第1题s7A中,必须按题目要求,定义函数count(s,f)。第2题s7B中,必须定义函数count(s)。
如果函数只能返回单一值,可能需要在主程序中多次调用函数。如果函数能够返回多个值,主程序中调用一次就可以了。
任务2:分类统计2
编写程序s7B.py,要求:
1、编写函数count(s):
函数值为列表,分别表示字符串s中数字、大写字母、小写字母和其他字符数目。
2、程序运行效果与s7A.py相同。
任务3:方差计算
编写程序s7C.py,要求:
1、编写函数variance(*a,ndigits=2):
(1)参数ndigits指定函数值四舍五入保留到小数点后的位数
(2)参数*a用于接收传递的任意个数值
(3)函数值为传递的全部数值的方差(各数值与均值之差的平方和)
2、程序运行效果:
输入数值序列:156,29,316,25.72,90.81
输入方差需四舍五入保留到小数点后的位数:3
输出:方差=57672.314
"""
(1)函数参数
① 位置参数(教材P68)
def division(one, two): #函数定义
return (one / two)
#主程序
print(division(6, 2)) #函数调用
调用函数时根据函数定义的参数位置来传递参数。实参和形参的顺序必须严格一致,且参数数量必须相同。位置参数是Python中最常用的调用形式。
② 关键字参数
def info(name, age, address): #函数定义
print(f'姓名:{name},年龄:{age},地址:{address}')
#主程序
info("李婷婷", age=23, address="山东") #函数调用
info("李婷婷", address="山东", age=23)
函数调用,通过“键--值”形式加以指定。允许函数调用时参数的顺序与声明不一致。有位置参数时,位置参数必须在关键字参数的前面,关键字参数之间不存在先后顺序。
③ 默认参数
def info(name, age, sex="男"): #函数定义
print(f'姓名:{name},年龄:{age},性别:{sex}')
#主程序
info("张三", 20) #形参sex使用默认值"男"
info("李婷婷", 21, "女") #形参sex使用实参值"女"
定义函数时,形参可赋值。调用函数时如果不传递值,则使用该默认值。所有位置参数必须出现在默认参数前,包括函数定义和调用。
④ 不定长参数*args(包裹位置参数)
def fun(a, b, *args):
print(a,b)
print(args)
#主程序
fun(1, 2, 3, 4, 5, 6)
输出:
1 2
(3, 4, 5, 6)
*args用于接收不定数量的位置参数,调用函数时传入的所有参数被*args接收后以元组形式保存。
def fun(a, b, *args):
print(a,b)
print(args)
#主程序
t=(3,4,5,6)
fun(1, 2,*t)
输出:
1 2
(3, 4, 5, 6)
传递实参时,可以在元组参数前添加*,程序会自动将元组中的元素依次作为参数传递。
⑤ 不定长参数**args(包裹关键字参数)
def fun(a, b, **kwargs):
print(a, b)
print(kwargs)
#主程序
fun(1, 2, x=3, y=4)
输出:
1 2
{'x': 3, 'y': 4}
**kwargs用于接收不定数量的关键字参数,调用函数时传入的所有参数被**kwargs接收后以字典形式保存。
(2)对键盘输入的数值序列处理
>>>s=input("输入数值序列:")
输入数值序列: 156,29,316,25.72,90.81
>>>s
'156,29,316,25.72,90.81'
对键盘输入的数值序列处理,前面实验4的s4A.py中,已经接触过一次了:
输入m,n:3,1000
如何将3和1000,分别赋值给m和n两个变量?
函数input( )接受的内容,是字符串,不能直接对其进行求和、求平均值。后面实验11文件操作中,read( )、readline( )等方法,从文件中读取的内容,也都是字符串,都需要后续处理。
方法①:推导式转换
s=input("输入数值序列:")
x=s.split(",") #字符串分割,得到列表x
a=[ float(i) for i in x ] #推导式生成列表a,列表元素转换为浮点型
print("average=",sum(a)/len(a))
程序运行结果:
输入数值序列:156,29,316,25.72,90.81
average= 123.506
使用a=( float(i) for i in x ),推导式生成元组a,一样可以求和、求平均值。
方法②:eval函数
s=input("输入数值序列:")
a=eval(s)
print("average=",sum(a)/len(a))
程序运行结果:
输入数值序列:156,29,316,25.72,90.81
average= 123.506
eval( )函数作用,是计算字符串中的有效Python表达式,并返回一个对象。简单理解,就是去掉字符串两端的引号。得到的结果是什么?Anything is possible。
方法③ :map函数(教材P73)
s=input("输入数值序列:")
x=s.split(",")
a = tuple(map(float, x))
print("average=",sum(a)/len(a))
map函数是Python内置的高阶函数,可以将其他函数作为参数或返回结果。
格式:map(function, iterable)
map函数接收的两个参数,一个是函数,一个是序列,其功能是将序列中的值处理,再依次返回至列表内。
>>>s="156,29,316,25.72,90.81"
>>>x=s.split(",")
>>>x
['156', '29', '316', '25.72', '90.81'] #列表x中的元素,都是字符串
>>>a = tuple(map(float, x)) #将列表x中的元素,转换为float
>>>a
(156.0, 29.0, 316.0, 25.72, 90.81) #tuple生成的是元组
>>>a = list(map(float, x))
>>>a
[156.0, 29.0, 316.0, 25.72, 90.81] #list生成的是列表
附加练习:
参考教材P30,编写函数fun(n)。在主程序中调用函数fun( ),输出所有水仙花数。
程序输出结果:
153
370
371
407

