Python · 3 分钟阅读
`lambda` 和 `map`
目录
lambda 是 匿名函数,map 把一个函数应用到可迭代对象的每个元素。两者
配合能让代码短小精悍;不过现代 Python 倾向用 推导式 替代它们。
1. lambda 表达式
# 传统函数
def add(x, y):
return x + y
# 等价的 lambda
add = lambda x, y: x + y
print(add(2, 3)) # 5
要点:
- 语法:
lambda 参数: 表达式 - 只能有一个表达式,会自动返回其结果。
- 不能写语句(
if/for/return等),但表达式里可以三元x if cond else y。 - 适合“一行就够”的小函数;命名函数的可读性更好时用
def。
1.1 排序 key
pairs = [(1, "one"), (2, "two"), (3, "three")]
pairs.sort(key=lambda p: p[1]) # 按第二个元素排序
print(pairs)
# [(3, 'three'), (1, 'one'), (2, 'two')]
1.2 提取字段
users = [{"name": "Ann", "age": 30}, {"name": "Bob", "age": 25}]
sorted(users, key=lambda u: u["age"])
2. map 函数
map(function, iterable, ...)
- 把
function应用到每个元素,返回一个 迭代器。 - 支持多个可迭代对象,
function参数数量要对应。 - 惰性:要拿结果用
list()/tuple()包一下。
def square(x):
return x * x
list(map(square, [1, 2, 3, 4])) # [1, 4, 9, 16]
多个可迭代对象:
a = [1, 2, 3]
b = [4, 5, 6]
list(map(lambda x, y: x + y, a, b)) # [5, 7, 9]
当可迭代对象 长度不一致 时,
map以 最短 的为准。
3. 综合示例
a = [1, 2, 3]
b = [4, 5, 6]
# 两个列表相加
print(list(map(lambda x, y: x + y, a, b))) # [5, 7, 9]
# 点积
print(sum(map(lambda x, y: x * y, a, b))) # 32
4. 推导式是更好的现代写法
nums = [1, 2, 3, 4]
# 平方
list(map(lambda x: x * x, nums)) == [x * x for x in nums] # True
# 求和
list(map(lambda x, y: x + y, a, b)) == [x + y for x, y in zip(a, b)]
优先用推导式——更直观、性能通常更好(特别在已经有现成函数时
map
才有微弱优势)。
5. 什么时候用 lambda + map?
-
已经有现成函数,只想“套一层参数”:
names = ["a.txt", "b.log"] list(map(Path, names)) # [Path('a.txt'), Path('b.log')] -
想要 惰性(处理极大数据流):
stream = map(int, open("numbers.txt")) # 一行一行转,不一次性加载 for n in stream: ... -
排序 /
min/max/sorted的key参数里需要一次性函数。
6. 替代品速查
| 场景 | 替换为 |
|---|---|
map(f, xs) |
[f(x) for x in xs] 或 (f(x) for x in xs) |
filter(f, xs) |
[x for x in xs if f(x)] |
简单 key=lambda x: ... |
operator.itemgetter / attrgetter |
| 复杂分支 | 普通 def 函数 |
| 性能关键 | numpy / pandas 向量化 |
7. 小结
lambda是匿名函数,只放一个表达式。map(func, *iterables)把函数应用到每个元素,惰性返回迭代器。- 现代代码优先用推导式;
map在已有命名函数或流式场景仍有价值。 lambda+ 排序/聚合是常见组合,可读性也好。