本文汇总了九个经典的Python函数编程练习题,涵盖基本运算、递归、数学计算、全局变量、方程求解、数值微分、可变参数以及递归处理列表等知识点。每个例子都提供完整代码,并深入分析其设计思路与实现细节。
1. 基本函数定义与调用
def cal(a, b):
return a - b
a = int(input())
b = int(input())
print(cal(a, b))
print(cal(b, a))
分析:
定义了一个简单的减法函数cal,接收两个参数并返回它们的差。程序依次输出a-b和b-a,演示了参数顺序对结果的影响。通过这个例子可以理解函数的基本定义、参数传递以及函数复用。
2. 递归函数:类斐波那契数列
def f(n):
if n == 1:
return 2
elif n == 2:
return 3
else:
return f(n - 1) + f(n - 2)
n = int(input())
print(f(n))
分析:
该递归函数与斐波那契数列类似,但初始值不同:f(1)=2,f(2)=3,后续每一项是前两项之和。递归必须要有基线条件(n==1或n==2),否则会无限递归。此例展示了递归的简洁性,但需注意当n较大时可能产生大量重复计算(可用记忆化优化)。
3. 函数与数学计算:球表面积
import math
def f(r):
return 4 * math.pi * r * r
for i in [1, 2, 4, 9, 10, 13]:
print(f"{f(i):.2f}")
分析:
计算球体表面积公式:(4\pi r^2)。程序遍历给定半径列表,使用格式化字符串保留两位小数输出。体现了数学库math的调用、循环结构以及格式化输出。
4. 摄氏度转华氏度
# coding:utf-8
deg = float(input())
def F(C):
return 9 * C / 5 + 32
print("%.2f" % (F(deg)))
分析:
摄氏度转华氏度的标准公式:(F = \frac{9}{5}C + 32)。函数F接收摄氏度,返回华氏度。输出时使用旧式格式化保留两位小数。注意输入转换为浮点数。
5. 全局变量与函数调用计数
# coding:utf-8
counter = 0
def access():
global counter
counter = counter + 1
for i in range(5):
access()
print(counter)
分析:
演示了如何在函数内部修改全局变量。关键字global声明counter为全局变量,每次调用access()使其自增1。循环5次后输出5。这是理解变量作用域和全局状态管理的基础示例。
6. 二次方程求根(两种版本)
版本一:返回列表或字符串
from math import sqrt
a = float(input()); b = float(input()); c = float(input())
def roots(a, b, c):
s = b * b - 4 * a * c
if s < 0:
return 'inf'
elif s == 0:
return [-b / (2 * a)]
else:
x1 = (-b + sqrt(s)) / (2 * a)
x2 = (-b - sqrt(s)) / (2 * a)
return x1, x2
print(roots(a, b, c))
版本二:限定 a != 0 并返回元组
from math import sqrt
a = float(input()); b = float(input()); c = float(input())
def roots(a, b, c):
s = b * b - 4 * a * c
if s < 0:
return 'inf'
elif s == 0:
return (-b / (2 * a), -b / (2 * a))
else:
x1 = (-b + sqrt(s)) / (2 * a)
x2 = (-b - sqrt(s)) / (2 * a)
return (x1, x2)
if a != 0:
print(roots(a, b, c))
分析:
两个版本都计算一元二次方程 (ax^2+bx+c=0) 的根。
- 判别式 (s = b^2 - 4ac)。
- 若 (s < 0) 返回字符串
'inf'(表示无实数根)。 - 若 (s = 0) 返回一个根(版本一用列表,版本二用元组)。
- 若 (s > 0) 返回两个根。
版本二额外判断了a != 0,确保方程是二次的。通过比较可理解不同返回类型(列表、元组、字符串)的灵活运用。
7. 数值微分(两种精度)
版本一:使用 delX = 0.001
from math import sin, cos
delX = 0.001
x = float(input())
def diff(f):
return lambda x: (f(x + delX) - f(x - delX)) / (2 * delX)
print("%.2f" % (diff(sin)(x)))
版本二:使用 delX = 0.01
from math import sin, cos
x = float(input())
def diff(f):
delX = 0.01
return lambda x: (f(x + delX) - f(x - delX)) / (2 * delX)
print("%.6f" % (diff(sin)(x)))
分析:
数值微分采用中心差分公式:(f'(x) \approx \frac{f(x+h)-f(x-h)}{2h}),其中(h)为步长。
diff是一个高阶函数,接收一个函数f,返回一个lambda函数,该函数计算f在任意点x的近似导数。- 版本一的步长为0.001,输出保留两位小数;版本二步长为0.01,输出保留六位小数。步长越小理论上精度越高,但过小可能引入舍入误差。本例展示了函数作为参数和返回值的强大特性。
8. 可变参数求和与 reduce
import random
from functools import reduce
n = input() # useless
n = random.randint(5, 10)
L = []
for i in range(n):
L.append(random.randint(1, n))
def sum_of_paras(*arg):
su = 0
for i in arg:
su = su + i
return su
strcall = "sum_of_paras(";
strcall += reduce(lambda x, y: x + "," + y, [str(s) for s in L])
strcall += ")"
if eval(strcall) == sum(L):
print("Y")
else:
print("N")
分析:
*arg表示可变参数,可以接收任意数量的位置参数,函数内部将其作为元组处理。- 手动构造了一个字符串
strcall,例如"sum_of_paras(3,5,2)",然后通过eval动态调用该函数。 - 使用
reduce和lambda将列表元素用逗号连接。 - 最后比较动态调用的结果与内置
sum(L)是否一致,输出"Y"或"N"。
此例综合了可变参数、字符串构造、eval动态执行以及函数式编程工具reduce。
9. 递归求绝对值之和
Lst = input()
Lst = Lst.split(',')
def abs_sum(L):
if not L: # 空列表,递归终止条件
return 0
return abs(int(L[0])) + abs_sum(L[1:])
print(abs_sum(Lst))
分析:
递归处理列表:每次处理第一个元素(取绝对值),然后递归处理剩余部分。基线条件是空列表返回0。注意输入是以逗号分隔的字符串,需先用split(',')拆分成字符串列表,再转换为整数并求绝对值。递归写法简洁优雅,但对于长列表可能栈溢出,实际中常用迭代。
总结
以上九个练习涵盖了Python函数编程的多个重要方面:
- 基础:函数定义、参数传递、返回值。
- 递归:斐波那契变种、列表处理。
- 作用域:全局变量与
global关键字。 - 数学计算:公式实现、方程求解、数值微分。
- 高阶函数:函数作为参数、返回
lambda函数。 - 可变参数:
*arg收集任意参数。 - 函数式工具:
reduce、map、lambda。 - 动态执行:
eval构造并调用代码。
掌握这些知识点,可以编写更灵活、更高效的Python程序。