💡 课堂例题

第 6 章 · 函数 · 共 8 题 · 代码均取自课堂讲稿

1
函数定义与调用
使用 def 定义函数,理解形参/实参、return 返回值、无return默认返回None。演示位置参数和关键字参数。
python
# 定义两数减法函数
def sub(x, y):      # x和y是形参
    return x - y

print(sub(1, 2))    # -1(1和2是实参)
print(sub(4, 6))    # -2

# 关键字参数
print(sub(y=1, x=2))  # 1

# 无参数函数
def list1():
    for i in range(10):
        print(f" {i} ", end="")
    print()
    # 没有return,返回值默认是None

list1()              # 输出数字序列
print(list1())       # None
2
函数的参数:强制位置、命名关键字、默认值
演示 / 强制位置参数、* 命名关键字参数、带默认值的参数。注意默认值参数必须在最后。
python
# 强制位置参数(Python 3.8+),只能用位置传参
def sub1(x, y, /):
    return x - y
print(sub1(2, 1))        # 1
# sub1(x=1, y=2)         # 报错!

# 命名关键字参数,只能用"参数名=值"传参
def sub2(*, x, y):
    return x - y
print(sub2(x=2, y=1))    # 1
# sub2(2, 1)             # 报错!

# 带默认值的参数
def sub3(x=20, y=10):
    return x - y
print(sub3())            # 10(使用默认值)
print(sub3(3, 3))        # 0(覆盖默认值)
3
可变参数 *args 和 **kwargs
*args 接收任意多个位置参数组装为元组,**kwargs 接收任意多个关键字参数组装为字典。
python
# 可变长度参数 *args
def add(*x):
    return sum(x)

print(add(1, 2))              # 3
print(add(1, 2, 3, 4, 5))     # 15

# 可变关键字参数 **kwargs
def foo(*args, **kwargs):
    print("位置参数:", args)       # 元组
    print("关键字参数:", kwargs)    # 字典

foo(3, 2.1, True, name='骆昊', age=43, gpa=4.95)
# 位置参数: (3, 2.1, True)
# 关键字参数: {'name': '骆昊', 'age': 43, 'gpa': 4.95}
4
变量的作用域:局部、全局、嵌套
理解 LEGB 规则。global 关键字修改全局变量,nonlocal 关键字修改外层函数的变量。
python
# 全局变量
n = 100

def ex2():
    global n          # 声明要修改全局变量
    n = n * 2
    print("函数内部:", n)

ex2()                 # 函数内部: 200
print("函数外部:", n)  # 函数外部: 200

# 嵌套作用域
def t2():
    num = 10
    def t3():
        nonlocal num  # 声明来自外层函数
        num = num + 5
        print("内层:", num)
    t3()
    print("外层:", num)

t2()  # 内层: 15 / 外层: 15

# 内置作用域
print(len([1, 2, 3]))  # 3 — len是内置函数
num = int("10")
print(num)             # 10 — int是内置函数
5
递归函数:阶乘
递归三要素:明确函数功能 → 终止条件 → 等价关系式。演示 n! = n × (n-1)! 的递归实现。
python
def ni(n):
    if n == 0 or n == 1:    # 终止条件
        return 1
    else:
        return n * ni(n - 1)  # 等价关系式

print(ni(5))  # 120
# 计算过程: 5*ni(4) → 5*4*ni(3) → 5*4*3*ni(2) → 5*4*3*2*ni(1) → 5*4*3*2*1 = 120

# 递归输出 1→10 的两种写法
def num(n):        # 正序:输出在递归前
    if n <= 10:
        print(n)
        num(n + 1)
num(1)             # 1 2 3 4 5 6 7 8 9 10

def num(n):        # 输出在递归后(看似倒序)
    if n >= 1:
        num(n - 1)
        print(n)
num(10)            # 也是 1 2 3 4 5 6 7 8 9 10
6
理解递归调用过程
"递归前"在进入下层前执行(正序),"递归后"在从下层返回后执行(逆序)。体会栈的先入后出特性。
python
def p(n):
    if n == 0:
        return
    print('递归前->', n)   # 进入下一层之前执行
    p(n - 1)                # 递归调用
    print('递归后->', n)   # 从下一层返回之后执行

p(5)
# 输出:
# 递归前-> 5      ← 依次深入
# 递归前-> 4
# 递归前-> 3
# 递归前-> 2
# 递归前-> 1
# 递归后-> 1      ← 依次返回
# 递归后-> 2
# 递归后-> 3
# 递归后-> 4
# 递归后-> 5
7
lambda 匿名函数
lambda 参数: 表达式。一行定义简单函数,常搭配 map/filter/sorted/reduce 使用。演示各种参数形式。
python
# 基本用法
add = lambda x, y: x + y
print(add(1, 3))    # 4

# 直接调用
print((lambda x, y: x ** y)(5, 2))  # 25

# 搭配三元运算符
is_odd = lambda n: "奇数" if n % 2 != 0 else "偶数"
print(is_odd(7))    # 奇数

# 各种参数形式
func = lambda: "Hello!"              # 无参数
func = lambda x: x ** 2              # 单参数
func = lambda x, y=2: x ** y         # 默认参数
func = lambda *args: sum(args)       # 可变参数
func = lambda **kw: len(kw)          # 关键字可变参数

# lambda作为函数返回值
def make_operation(operator):
    if operator == "+":
        return lambda x, y: x + y
    elif operator == "*":
        return lambda x, y: x * y

add = make_operation("+")
print(add(3, 4))       # 7
mul = make_operation("*")
print(mul(3, 4))       # 12
8
高阶函数:map、filter、reduce、sorted
map 批量处理,filter 批量筛选,reduce 累积计算,sorted 排序。全部搭配 lambda 使用。
python
# map():将列表元素平方
nums = [1, 2, 3, 4, 5]
print(list(map(lambda x: x ** 2, nums)))  # [1,4,9,16,25]
# 两个列表对应元素相加
print(list(map(lambda x, y: x + y, [10,20,30], [5,15,25])))  # [15,35,55]

# filter():筛选奇数
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(filter(lambda x: x % 2 != 0, nums)))  # [1,3,5,7,9]
# 筛选长度>3的字符串
print(list(filter(lambda s: len(s) > 3, ["a","ab","abc","abcd"])))  # ['abcd']
# filter(None)过滤假值
print(list(filter(None, [0, 1, "", "hello", None, False])))  # [1,'hello']

# reduce():累积计算
from functools import reduce
print(reduce(lambda a, b: a + b, [1,2,3,4,5]))    # 15(累加)
print(reduce(lambda a, b: a * b, [2,3,4,5]))      # 120(累乘)
# 字符串拼接
print(reduce(lambda a, b: a + b, ["我","爱","Python"]))  # 我爱Python

# sorted():自定义排序
arr = ['apple', 'banana', 'cherry', 'date']
print(sorted(arr, key=lambda s: len(s)))  # 按长度排序

people = [{'name':'alice','age':15},{'name':'bob','age':25},{'name':'charlie','age':30}]
print(sorted(people, key=lambda x: x['age']))  # 按年龄排序