Python函数进阶:*args和**kwargs、lambda匿名函数,让代码瞬间简洁
·
Python函数进阶:*args和**kwargs、lambda匿名函数,让代码瞬间简洁
上一篇文章讲了函数基础,这篇文章讲函数的三个进阶特性:*args、**kwargs、lambda。学会这三个,你的代码会简洁很多。
一句话概括
这篇文章解决一个问题:**掌握 *args、kwargs 和 lambda 的用法,让函数更灵活。
*args:接收任意数量的位置参数
有时候我们不知道函数会有多少个参数,*args 解决了这个问题。
def sum_all(*args):
"""求所有参数的和"""
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
print(sum_all()) # 0(没有参数)
args 是一个元组,包含了所有传入的位置参数。
**kwargs:接收任意数量的关键字参数
类似地,**kwargs 接收任意数量的关键字参数。
def print_info(**kwargs):
"""打印所有关键字参数"""
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="小明", age=18, city="北京")
# 输出:
# name: 小明
# age: 18
# city: 北京
kwargs 是一个字典。
组合使用 *args 和 **kwargs
def func(*args, **kwargs):
print(f"位置参数:{args}")
print(f"关键字参数:{kwargs}")
func(1, 2, 3, name="小明", age=18)
# 输出:
# 位置参数:(1, 2, 3)
# 关键字参数:{'name': '小明', 'age': 18}
实战:用 *args 和 **kwargs 简化代码
练习1:动态格式化
def create_message(template, *args, **kwargs):
"""模板消息"""
# 用传入的参数替换模板中的占位符
message = template.format(*args, **kwargs)
return message
msg = create_message(
"您好,{name}!您的订单{order_id}已发货,预计{day}天后送达。",
name="张三",
order_id="ORD12345",
day="3"
)
print(msg)
# 您好,张三!您的订单ORD12345已发货,预计3天后送达。
练习2:日志记录器
def log(level, *args, **kwargs):
"""简化版日志记录"""
# 如果传了 time 参数就用,否则用当前时间
time = kwargs.pop("time", None)
if time:
print(f"[{level}] {time}: {' '.join(str(a) for a in args)}")
else:
print(f"[{level}] {' '.join(str(a) for a in args)}")
log("INFO", "服务器启动")
log("ERROR", "连接失败", "重试次数:", 3)
log("DEBUG", "用户登录", "user_id:", 12345, time="10:30:00")
lambda:匿名函数
有时候需要一个简单的函数,但懒得写 def ...,这时候用 lambda。
lambda 的基本语法
# 普通函数
def add(x, y):
return x + y
# lambda版本
add = lambda x, y: x + y
# 调用
print(add(10, 20)) # 30
lambda 参数: 返回值
lambda 适合的场景
1. 作为参数传给其他函数
# 按名字排序
names = ["Charlie", "Alice", "Bob"]
sorted_names = sorted(names, key=lambda x: x.lower())
print(sorted_names) # ['Alice', 'Bob', 'Charlie']
# 按成绩排序
students = [("小明", 85), ("小红", 92), ("小李", 78)]
sorted_students = sorted(students, key=lambda x: x[1], reverse=True)
print(sorted_students) # [('小红', 92), ('小明', 85), ('小李', 78)]
# map:对每个元素做操作
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers))
print(squares) # [1, 4, 9, 16, 25]
# filter:过滤元素
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]
2. 简化返回函数的函数
# 普通写法
def make_multiplier(n):
def multiplier(x):
return x * n
return multiplier
# 用lambda简化
make_multiplier = lambda n: lambda x: x * n
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
列表排序:key 参数详解
sorted() 和 list.sort() 的 key 参数非常有用:
# 按字符串长度排序
words = ["Python", "is", "great"]
sorted_words = sorted(words, key=len)
print(sorted_words) # ['is', 'great', 'Python']
# 按字典的某个字段排序
students = [
{"name": "小明", "score": 85},
{"name": "小红", "score": 92},
{"name": "小李", "score": 78},
]
sorted_students = sorted(students, key=lambda x: x["score"], reverse=True)
for s in sorted_students:
print(f"{s['name']}: {s['score']}")
map/filter/reduce
这是函数式编程的三个核心函数:
map:对每个元素做操作
# 不用map
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n ** 2)
# 用map
squares = list(map(lambda x: x ** 2, numbers))
# 等价的列表推导式
squares = [x ** 2 for x in numbers]
filter:过滤元素
# 不用filter
numbers = [1, 2, 3, 4, 5]
evens = []
for n in numbers:
if n % 2 == 0:
evens.append(n)
# 用filter
evens = list(filter(lambda x: x % 2 == 0, numbers))
# 等价的列表推导式
evens = [x for x in numbers if x % 2 == 0]
reduce:汇总所有元素
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# 不用reduce
product = 1
for n in numbers:
product *= n
# 用reduce
product = reduce(lambda x, y: x * y, numbers, 1) # 1是初始值
print(product) # 120
常见问题FAQ
Q1:什么时候用 lambda?
- 函数很简单,只用一次
- 作为参数传给另一个函数(sorted、map、filter等)
- 想让代码更简洁
如果函数逻辑复杂(超过一行),建议用 def。
Q2:*args 和 **kwargs 可以同时用吗?
可以,但*args必须在**kwargs前面:
def func(*args, **kwargs):
pass
Q3:lambda 能访问外部变量吗?
可以,这叫闭包:
make_adder = lambda x: lambda y: x + y
add5 = make_adder(5)
print(add5(10)) # 15
写在最后
这篇文章覆盖了函数的三个进阶特性:
*args:接收任意数量的位置参数(元组)**kwargs:接收任意数量的关键字参数(字典)lambda:匿名函数,简洁定义简单函数
下一篇文章:Python 文件读写,读取TXT和CSV、处理异常。
参考资料:
更多推荐
所有评论(0)