函数基础
让代码可复用 —— 从重复劳动到优雅编程
什么是函数?
函数是可重复使用的代码块,接受输入(参数),执行操作,返回输出(结果)。
类比:
- Stata:
program define - R:
function() - 数学: f(x) = 2x + 1
为什么需要函数?
- 避免重复代码(DRY 原则:Don't Repeat Yourself)
- 代码更易维护
- 提高可读性
- 便于测试和调试
定义函数
基本语法
python
def function_name(parameters):
"""文档字符串(可选)"""
# 函数体
return result示例 1:简单函数
python
def greet():
"""打印问候语"""
print("Hello, World!")
# 调用函数
greet() # 输出: Hello, World!示例 2:带参数的函数
python
def greet_person(name):
"""根据姓名打印问候语"""
print(f"Hello, {name}!")
greet_person("Alice") # 输出: Hello, Alice!
greet_person("Bob") # 输出: Hello, Bob!示例 3:带返回值的函数
python
def calculate_bmi(weight, height):
"""计算BMI
参数:
weight: 体重(千克)
height: 身高(米)
返回:
BMI值
"""
bmi = weight / (height ** 2)
return bmi
# 使用函数
result = calculate_bmi(70, 1.75)
print(f"BMI: {result:.2f}") # BMI: 22.86对比:Stata vs R vs Python
Stata 版本
stata
* Stata
program define calc_bmi
args weight height
gen bmi = `weight' / (`height'^2)
endR 版本
r
# R
calc_bmi <- function(weight, height) {
bmi <- weight / (height^2)
return(bmi)
}
result <- calc_bmi(70, 1.75)Python 版本
python
# Python
def calc_bmi(weight, height):
bmi = weight / (height ** 2)
return bmi
result = calc_bmi(70, 1.75)实战案例
案例 1:收入税计算
python
def calculate_tax(income):
"""计算个人所得税(累进税率)
税率:
0-50000: 10%
50001-100000: 20%
100001+: 30%
"""
if income <= 50000:
tax = income * 0.10
elif income <= 100000:
tax = 50000 * 0.10 + (income - 50000) * 0.20
else:
tax = 50000 * 0.10 + 50000 * 0.20 + (income - 100000) * 0.30
return tax
# 使用
incomes = [45000, 75000, 120000]
for income in incomes:
tax = calculate_tax(income)
net = income - tax
print(f"收入: ${income:,}, 税: ${tax:,.0f}, 税后: ${net:,.0f}")案例 2:数据验证
python
def validate_age(age):
"""验证年龄是否合理
返回:
(is_valid, message): 布尔值和提示信息
"""
if age < 0:
return False, "年龄不能为负数"
elif age > 120:
return False, "年龄过大"
elif age < 18:
return False, "未成年"
else:
return True, "年龄有效"
# 使用
ages = [25, -5, 150, 15, 30]
for age in ages:
is_valid, message = validate_age(age)
status = "" if is_valid else ""
print(f"{status} 年龄 {age}: {message}")案例 3:描述性统计
python
def describe_data(data):
"""计算描述性统计
返回字典包含: n, mean, median, min, max
"""
n = len(data)
mean = sum(data) / n
sorted_data = sorted(data)
median = sorted_data[n // 2]
return {
'n': n,
'mean': mean,
'median': median,
'min': min(data),
'max': max(data)
}
# 使用
scores = [85, 92, 78, 90, 88, 76, 95, 82]
stats = describe_data(scores)
print(f"样本量: {stats['n']}")
print(f"平均分: {stats['mean']:.2f}")
print(f"中位数: {stats['median']}")
print(f"最低分: {stats['min']}")
print(f"最高分: {stats['max']}")返回值
1. 返回单个值
python
def square(x):
return x ** 2
result = square(5) # 252. 返回多个值(元组)
python
def calculate_stats(data):
mean = sum(data) / len(data)
maximum = max(data)
minimum = min(data)
return mean, maximum, minimum # 自动打包为元组
# 解包接收
avg, max_val, min_val = calculate_stats([1, 2, 3, 4, 5])
print(avg, max_val, min_val) # 3.0 5 13. 返回字典
python
def get_student_info(name, age, major):
return {
'name': name,
'age': age,
'major': major,
'status': 'active'
}
student = get_student_info("Alice", 25, "Economics")
print(student['name']) # Alice4. 无返回值
python
def print_report(data):
"""只打印,不返回"""
for item in data:
print(item)
# 没有 return 语句,默认返回 None
result = print_report([1, 2, 3])
print(result) # None函数参数类型
1. 位置参数
python
def power(base, exponent):
return base ** exponent
result = power(2, 3) # 2^3 = 82. 默认参数
python
def greet(name, greeting="Hello"):
"""greeting 有默认值"""
return f"{greeting}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Bob", "Hi")) # Hi, Bob!
print(greet("Carol", greeting="Hey")) # Hey, Carol!3. 关键字参数
python
def register_student(name, age, major, gpa=3.0):
print(f"{name}, {age}岁, 专业: {major}, GPA: {gpa}")
# 位置传参
register_student("Alice", 25, "Economics")
# 关键字传参(顺序可变)
register_student(major="Sociology", age=28, name="Bob", gpa=3.5)
# 混合(位置参数必须在前)
register_student("Carol", 26, major="Political Science")4. 可变参数(*args)
python
def calculate_average(*numbers):
"""接受任意数量的数字"""
if not numbers:
return 0
return sum(numbers) / len(numbers)
print(calculate_average(1, 2, 3)) # 2.0
print(calculate_average(10, 20, 30, 40)) # 25.0
print(calculate_average(5)) # 5.05. 关键字可变参数(**kwargs)
python
def create_respondent(**info):
"""接受任意数量的关键字参数"""
for key, value in info.items():
print(f"{key}: {value}")
create_respondent(
name="Alice",
age=30,
income=75000,
education="Master's"
)最佳实践
1. 函数命名
python
# 不好的命名
def f(x, y):
return x + y
# 好的命名(动词开头,描述功能)
def calculate_total(price, quantity):
return price * quantity
def validate_email(email):
return '@' in email
def is_adult(age):
return age >= 182. 单一职责原则
python
# 函数做太多事
def process_data(data):
# 清洗数据
# 计算统计
# 生成图表
# 保存结果
pass
# 拆分为多个函数
def clean_data(data):
"""只负责清洗"""
pass
def calculate_stats(data):
"""只负责计算"""
pass
def plot_data(data):
"""只负责画图"""
pass3. 文档字符串
python
def calculate_correlation(x, y):
"""计算两个变量的相关系数
参数:
x (list): 第一个变量的数据
y (list): 第二个变量的数据
返回:
float: 相关系数 (-1 到 1)
示例:
>>> calculate_correlation([1, 2, 3], [2, 4, 6])
1.0
"""
# 函数实现
pass练习题
练习 1:温度转换
python
# 编写两个函数:
# 1. celsius_to_fahrenheit(c): 摄氏转华氏
# 2. fahrenheit_to_celsius(f): 华氏转摄氏
# 公式: F = C × 9/5 + 32练习 2:成绩评级
python
# 编写函数 grade_to_letter(score)
# 90-100: A
# 80-89: B
# 70-79: C
# 60-69: D
# <60: F练习 3:列表统计
python
# 编写函数 analyze_scores(scores)
# 返回字典包含:
# - count: 数量
# - mean: 平均分
# - passing_rate: 及格率(>=60)
# - grade_distribution: 各等级人数
scores = [85, 92, 78, 65, 90, 55, 88, 76, 95, 70]
result = analyze_scores(scores)下一步
在下一节中,我们将学习 函数参数的高级用法,包括参数解包、lambda 函数等。
继续前进!