lambda:一次性小函数
square = lambda x: x ** 2
square(5) # 25
# 等价于
def square(x):
return x ** 2
只能写一个表达式,不能有 if/for/return。主要用作高阶函数的参数:
nums = [1, 2, 3, 4, 5]
nums.sort(key=lambda x: -x) # 按相反数排,等于降序
filter(lambda x: x % 2 == 0, nums)
map:把函数应用到每个元素
list(map(str.upper, ["hello", "world"]))
# ['HELLO', 'WORLD']
list(map(lambda x: x ** 2, [1, 2, 3, 4]))
# [1, 4, 9, 16]
filter:保留满足条件的
list(filter(lambda x: x > 0, [-2, -1, 0, 1, 2]))
# [1, 2]
list(filter(None, [0, 1, "", "a", None, []]))
# [1, 'a'] None 表示"过滤掉假值"
reduce:累计
from functools import reduce
reduce(lambda a, b: a + b, [1, 2, 3, 4])
# 10 ((1+2)+3)+4
reduce(lambda a, b: a * b, [1, 2, 3, 4])
# 24
reduce(lambda a, b: a + b, [1, 2, 3, 4], 100)
# 110 初始值 100
Python 的取舍:推导式 vs map/filter
很多 Pythonista 更喜欢推导式:
# map / filter
list(map(lambda x: x ** 2, filter(lambda x: x > 0, nums)))
# 推导式(更易读)
[x ** 2 for x in nums if x > 0]
推导式赢——它更 Python。
map / filter 仍然有用的场景
方法引用(不需要写 lambda):
list(map(str.strip, lines)) # 比 [s.strip() for s in lines] 略简配合其他高阶函数:
from itertools import accumulate list(accumulate(map(int, "12345"), lambda a, b: a + b))流式处理大数据(map 返回迭代器,懒加载):
for line in map(str.strip, open("huge.txt")): process(line)
any / all:常被忘记的好东西
any(x > 0 for x in nums) # 有任意一个正数?
all(x > 0 for x in nums) # 全都是正数?
# 替代 for 找"有没有匹配"
any("error" in line for line in log_lines)
一条经验
写函数式 ≠ 写好代码。Python 不是 Haskell——什么用着舒服用什么。推导式 / 普通 for / map 都是工具,按场景选。
下一篇讲 functools 全家桶——partial / lru_cache 才是函数式在 Python 里最实用的部分。