Python入门到精通(四):从基础到高阶,函数完全指南

关注我不迷路,您的点赞+收藏,就是我坚持的动力!

引言:为什么函数如此重要

在前端开发中,我们习惯将UI拆分为可复用的组件。

在Python中,函数就是我们的“逻辑组件” — 它们封装特定功能,可以在不同地方重复使用,让代码更模块化、更易维护。

一、Python函数基础

函数是一段可以重复使用的代码块,它接收输入(参数),执行特定任务,然后返回结果。
关键字为def,代表定义一个函数。
函数的基本结构如下:

def 函数名(参数):
    # 函数体(执行具体操作)
    return 返回值

1.1 函数参数

函数的参数简单分为:
1)必须参数:调用时必须提供
2)默认参数:可以不提供,使用默认值

必须参数分为:
I. 位置参数:按照参数的位置依次传递的参数。

def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type} named {pet_name}.")
# 示例
describe_pet("cat", "大白猫") # I have a cat named 大白猫.

II. 关键字参数:通过参数名指定传递的参数,可以不按照顺序传递。

def describe_pet(pet_name="Whiskers", animal_type="cat"):
	print(f"I have a {animal_type} named {pet_name}.")
# 示例
describe_pet(pet_name= "大白猫") #I have a cat named 大白猫.

III. 可变参数:
*args:可变位置参数,可以接收任意数量的位置参数,存储为一个元组。
**kwargs:可变关键字参数,可以接收任意数量的关键字参数,存储为一个字典

# 可变参数 *args
def make_pizza(*toppings):
    print("Making pizza with:")
    for topping in toppings:
        print(f"- {topping}")
make_pizza("pepperoni", "cheese", "mushrooms")
''' 
Making pizza with:
- pepperoni
- cheese
- mushrooms
'''

# 关键字可变参数 **kwargs
def build_profile(first, last, **user_info):
    profile = {'first_name': first, 'last_name': last}
    profile.update(user_info)
    return profile
# 示例
rest = build_profile('albert', 'einstein', location='princeton', field='physics')
print(rest)
# {'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}

默认参数,即参数存在默认值,且为可选项,传递与否不影响

def make_shirt(size="L", message="I love Python"):
    print(f"Size: {size}, Message: {message}")
# 示例
make_shirt() # Size: L, Message: I love Python
make_shirt("M", "I don't know") # Size: M, Message: I don't know
make_shirt(message="HAHAHA") # Size: L, Message: HAHAHA

2.2 函数返回值

在Python中,函数使用return语句返回值,如果没有return语句,函数默认返回None。
返回值可以是任意类型,包括数字、字符串、列表、字典、甚至是函数或类实例

1)返回数字

def add(a, b)
	return a+b

2)返回多个值:实际返回的是元组

def get_point(a = 10, b = 10):
    x = a
    y = b
    return x, y
# 示例
point = get_point(10, 20) 
print(point) #(10, 20)
x_val, y_val = get_point(10, 20) # x_val:10, y_val: 20
print(x_val) # 10
print(y_val) # 20

3)返回函数:闭包

def multiplier(factor):
    def multiply(x):
        return x * factor
    return multiply
# 示例
double = multiplier(2)
print(double(5))  # 输出: 10

二、匿名函数:lambda

lambda函数是一种小型匿名函数。是一种简洁的定义单行函数的方式,可以接受任意数量的参数,但只能有一个表达式。

通常用于定义简单的、不会重复使用的函数,复杂函数请使用def定义常规函数。

2.1 基本语法:

# Lambda函数定义
lambda 参数1, 参数2..., 参数N: 表达式

# 示例
# 普通函数:计算长方形面积
def 计算面积(,):
    return*# Lambda版本
面积计算器 = lambda,:*print(f"面积: {面积计算器(5, 3)}")  # 输出:面积: 15

2.2 常见使用场景

1)场景1:简单数学运算

add = lambda a, b: a + b # 加法
is_even = lambda x: x % 2 == 0 # 偶数

2)场景2:配合map进行数据处理流水线处理

users = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]
# 获取用户年龄列表
ages = map(lambda user: user["age"], users) # map object
print(list(ages)) # [25, 30, 20]

3)场景3:配合sort进行排序‘

users = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]
# 根据年龄排序
users.sort(key=lambda user: user["age"])
print(users) 
# [{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]

4)场景4:条件表达式

grade_eval = lambda score: "优" if score >= 90 else "良" if score >= 60 else "不及格"
score = 80
print(grade_eval(score)) # 良

三、高阶函数:Python的函数式编程武器

高阶函数是指可以接收函数作为参数返回函数作为结果的函数
常用高阶函数如下

3.1 map():数据转换

map()函数,接收一个函数和一个或多个可迭代对象作为参数,然后将传入的函数依次作用到可迭代对象的每个元素上,并返回一个map对象(迭代器)

map() 的核心思想是 “映射”,把一个函数应用到序列的每个元素上,生成一个新的map对象。
为了看到map()的结果,我们通常将它转换为列表或其他可迭代对象。

# 使用语法
map(function, iterable1, ...iterableN)
# 示例
# 基础用法:转换列表
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
# 结果:[1, 4, 9, 16, 25]

# 实际应用:数据清洗
prices = ["$10.99", "$23.50", "$7.25", "invalid"]
clean_prices_map = map(lambda p: float(p.replace("$", "")) if p.startswith("$") else None, prices)
clean_prices = list(clean_prices_map)
# 结果:[10.99, 23.5, 7.25, None]

3.2 filter():数据筛选

filter函数用于从序列中筛选出满足指定条件的元素。它遍历序列中的每个元素,只保留那些通过"测试"的元素,过滤掉不符合条件的元素。

filter() 的核心思想是 “过滤” 或 “筛选”,拥有惰性求值的策略,仅在实际请求元素时才进行计算,可节省内存。

# 使用语法
filter(function, iterable)

# 示例
# 基础用法:筛选偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
# 结果:[2, 4, 6, 8, 10]

# 实际应用:过滤无效数据
data = [
    {"id": 1, "active": True},
    {"id": 2, "active": False},
    {"id": 3, "active": True},
    {"id": 4, "active": False}
]
active_users = list(filter(lambda user: user["active"], data))
# 结果:[{"id": 1, "active": True}, {"id": 3, "active": True}]

3.3 reduce():数据聚合

reduce()函数,用于对序列中的元素进行累积运算。它通过一个接收两个参数的函数,先对序列的前两个元素进行操作,然后将结果与下一个元素继续操作,如此累积下去,最终将整个序列缩减为单个值。

reduce() 的核心思想是 “归约” 或 “累积”。
Python 3 中,reduce() 已移到 functools 模块,需要导入使用

# 语法 initializer为初始值,可选
reduce(function, iterable[, initializer])

# 示例
from functools import reduce
# 计算累加
numbers = [1, 2, 3, 4, 5]
sum_result = reduce(lambda acc, curr: acc + curr, numbers, 0)
# 结果:15

# 计算乘积
product = reduce(lambda acc, curr: acc * curr, numbers, 1)
# 结果:120

# 查找最大值
max_value = reduce(lambda a, b: a if a > b else b, numbers)
# 结果:5

3.4 sorted():灵活排序工具

sorted() 用于对任何可迭代对象进行排序,返回一个新的已排序列表,而不会修改原始数据。

sorted() 使用 Timsort 算法(一种混合排序算法):接收可迭代对象并创建其元素的列表副本,根据 key 参数提取比较键,按照指定的顺序(升序或降序)对元素进行排序,返回包含排序后元素的新列表。

# 语法
sorted(iterable, key=None, reverse=False)
# key 排序条件 
# reverse 排序方向,默认升序 false

# 自定义排序规则
students = [
    {"name": "Alice", "grade": 85, "age": 20},
    {"name": "Bob", "grade": 92, "age": 22},
    {"name": "Charlie", "grade": 78, "age": 19}
]
# 按成绩降序,年龄升序排序
sorted_students = sorted(
    students,
    key=lambda s: (-s["grade"], s["age"])
)

四、函数常见使用场景

场景1:数据处理管道

假定一个电商价格处理场景,要筛选出有效的价格,并进行折扣处理,最后统计信息。经历数据过滤 -> 数据转换 -> 数据聚合的完整流程。

# 电商价格处理流程
def process_prices(prices):
    # 1. 过滤负数和零
    valid_prices = filter(lambda p: p > 0, prices)
    # 2. 应用折扣
    discounted = map(lambda p: p * 0.9, valid_prices)
    # 3. 计算统计信息
    stats = {
        'count': 0,
        'total': 0,
        'max': float('-inf'),
        'min': float('inf')
    }
    def update_stats(acc, price):
        acc['count'] += 1
        acc['total'] += price
        acc['max'] = max(acc['max'], price)
        acc['min'] = min(acc['min'], price)
        return acc
    return reduce(update_stats, discounted, stats)
# 使用示例
prices = [100, 200, -50, 150, 0, 300]
result = process_prices(prices)
print(result)  # {'count': 4, 'total': 675.0, 'max': 270.0, 'min': 90.0}

场景2:配置化行为

假定一个支付处理系统中的场景应用,每种支付方式有不同的手续费计算规则。
使用策略模式,通过lambda表达式来实现不同的支付策略,展示了使用函数式编程实现灵活、可扩展的算法选择机制。

# 策略模式:根据不同条件选择不同算法
# 创建支付处理器
def create_payment_processor(strategy_type):
    strategies = {
        'credit_card': lambda amount: f"信用卡支付 ${amount},手续费 ${amount * 0.03:.2f}",
        'paypal': lambda amount: f"PayPal支付 ${amount},手续费 ${amount * 0.02:.2f}",
        'alipay': lambda amount: f"支付宝支付 ${amount},手续费 ${amount * 0.01:.2f}"
    }
    return strategies.get(strategy_type, lambda amount: f"未知支付方式: ${amount}")

# 使用示例
processor = create_payment_processor('alipay')
print(processor(100))  # 支付宝支付 $100,手续费 $1.00

场景3:事件驱动架构

假定要实现一个简单的事件总线系统,用于处理事件的发布和订阅。

我们创建了一个EventBus类,它有两个主要方法:subscribe(订阅事件)和emit(触发事件)。
这个系统允许多个处理函数订阅同一个事件类型,当事件被触发时,所有订阅了该事件的处理函数都会被调用。

# 简单的事件总线系统
class EventBus:
    def __init__(self):
        self.handlers = {}
    # 订阅事件 - 普通函数
    def subscribe(self, event_type, handler):
        if event_type not in self.handlers:
            self.handlers[event_type] = []
        self.handlers[event_type].append(handler)
    # 触发事件 - 普通函数
    def emit(self, event_type, *args, **kwargs):
        if event_type in self.handlers:
            for handler in self.handlers[event_type]:
                handler(*args, **kwargs)

# 使用示例
bus = EventBus()
# 订阅事件
bus.subscribe('user_login', lambda user: print(f"日志: {user} 登录了"))
bus.subscribe('user_login', lambda user: print(f"欢迎 {user}!"))
bus.subscribe('user_logout', lambda user: print(f"再见 {user}!"))
# 触发事件
bus.emit('user_login', 'Alice')
# 输出:
# 日志: Alice 登录了
# 欢迎 Alice!

五、常见高频面试题

问题1:实现函数柯里化

要求:将多参数函数转换为一系列单参数函数。

A:柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

柯里化的工作原理:
1)定义一个内部函数 curried,它接受任意数量的参数(*args)。
2)检查已经传入的参数数量(len(args))是否大于等于原始函数(func)所需要的参数数量(func.code.co_argcount)。
2.1)如果是,则说明参数已经足够,直接调用原始函数并返回结果。
2.2)如果参数不够,则返回一个新的函数,这个函数接受更多的参数(*more_args),然后递归调用 curried,并将之前的参数和新的参数合并。

def curry(func):
    def curried(*args):
        if len(args) >= func.__code__.co_argcount:
            return func(*args)
        return lambda *more_args: curried(*(args + more_args))
    return curried

# 使用示例
@curry
def add_three(a, b, c):
    return a + b + c
# 多种调用方式
print(add_three(1, 2, 3))      # 6
print(add_three(1)(2)(3))      # 6
print(add_three(1, 2)(3))      # 6

问题2:实现compose函数(函数组合)

要求:实现函数组合,将多个函数组合成一个新函数。

A:compose函数接受任意数量的函数作为参数,然后返回一个新的函数,这个新的函数会按照从右向左的顺序依次应用这些函数。

def compose(*funcs):
    # 处理边界情况
    if not funcs:
        return lambda x: x
    # 仅一个函数,返回函数本身
    if len(funcs) == 1:
        return funcs[0]
    # 创建组合函数
    def composed(arg):
        result = arg
        # 从右向左执行
        for func in reversed(funcs):
            result = func(result)
        return result
    return composed

# 使用示例
def add_one(x):
    return x + 1
def double(x):
    return x * 2
def square(x):
    return x ** 2
# 组合函数:先加1,再平方,再翻倍
transform = compose(double, square, add_one)
print(transform(2))  # 18: (2+1)^2 * 2

六、总结

核心要点回顾

· 函数是Python的一等公民:可以赋值、传递、返回
· lambda是简洁的匿名函数:适合简单操作和函数式编程
· 高阶函数提升代码表达能力:map、filter、reduce、sorted等
· 函数式编程思维:关注"做什么"而不是"怎么做"

编码建议

· 对于复杂的、可重用的功能,使用普通函数。
· 对于简单的、一次性的操作,考虑使用匿名函数,但要注意可读性。
· 尽量使用内置函数来完成常见任务,提高效率和代码简洁性。

下一期预告

下一篇我们将深入学习Python高级特性之装饰器的原理和应用

装饰器是 Python 中一个强大且优雅的特性,它允许我们以简洁的方式增强函数或类的功能
掌握装饰器对于编写高质量的 Python 代码和理解高级 Python 代码库至关重要

如果觉得有帮助,请关注+点赞+收藏,这是对我最大的鼓励!
如有问题,请评论区留言

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周五不部署

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值