一、先搞懂灵魂配角:lambda 匿名函数

lambda 定位:一次性、极简逻辑专用临时函数

如果你只是临时写个简单计算、提取字段,不想费劲写def命名函数,直接上lambda。

语法模板:

lambda 参数: 返回表达式

✅ 优点:就地定义、用完即走,配合高阶函数堪称绝配

❌ 局限:只能写单行表达式,不能写if分支代码块、循环、多行逻辑

# 普通命名函数
def add(a, b):
    return a + b
print(add(2, 3))
lambda版本
add = lambda a, b: a + b
print(add(2, 3))
平方、立方随手写
square = lambda x: x ** 2
cube = lambda x: x ** 3
print(square(3), cube(3))  # 9 27

小冷知识:lambda函数没有正式名字,__name__统一输出<lambda>

f2 = lambda: print(888)
print(f2.__name__)  # <lambda>

忠告:复杂逻辑老老实实def,硬塞lambda只会把代码写成天书!

二、排序神器 sorted(),别和列表sort()搞混

sorted(可迭代对象, *, key=None, reverse=False)

核心要点:

  1. 返回全新列表,不会改动原数据;list.sort()才是原地修改
  2. key:最重要参数!自定义排序规则,接收一个函数
  3. reverse=False升序;reverse=True降序

基础用法:纯数字、字符串、元组直接排

lst1 = [1,2,4,6,9,0,3]
print(sorted(lst1))              # 升序
print(sorted(lst1, reverse=True))# 降序
字符串、元组通通支持,最终统一返回列表
str1 = "1246903"
print(sorted(str1,reverse=True))

重头戏:key 参数自定义排序依据

原始元素太复杂(元组、字典),不想对比整体,只想拿其中某个字段当排序标尺。

示例:学生元组 (姓名, 分数)

stu = [("小明",92),("小红",85),("小刚",96)]
传统def写法
def get_score(t):
return t[1]
res = sorted(stu, key=get_score)
lambda极简写法(推荐临时使用)
res = sorted(stu, key=lambda t: t[1])
print(res)

底层逻辑通俗解释

sorted会遍历所有元素,把每个元素丢进key绑定的函数,拿到“对比用的数字”;依靠这个数字完成大小排序,最终排出来的还是原始完整数据,不是用来对比的数字!

字典列表排序日常最多:

stu = [
    {"name":"小明","grade":92},
    {"name":"小红","grade":85},
    {"name":"小刚","grade":96}
]
按分数升序
res = sorted(stu, key=lambda item: item["grade"])
print(res)

三、map() 映射函数:批量加工每一条数据

map(处理函数, 可迭代对象1, 可迭代对象2...)

作用:遍历序列中每一个元素,丢进函数加工,返回加工后的结果

⚠️ map不会直接输出列表,得到的是map迭代器,必须套list()查看结果。

基础示例:列表全部数字平方

nums = [1, 2, 3, 4]
传统for循环
res = []
for n in nums:
res.append(n*n)
map + def
def square(x):
return x**2
res = list(map(square, nums))
map + lambda(最简)
res = list(map(lambda x: x**2, nums))
print(res) # [1,4,9,16]

工程&刷题封神场景:文本批量类型转换

读取输入字符串列表,批量转数字,没人能避开这个写法!

str_nums = ["10", "20", "30"]
res = list(map(int, str_nums))
print(res) # [10,20,30]
算法题目万能输入模板,背下来!
data = list(map(int, input("输入数字空格隔开:").split()))

多序列并行处理

传入多个序列,函数对应接收多个参数;长度不一致时,以最短序列为准,多余元素直接丢弃

a = [1,2,3]
b = [10,20,30]
res = list(map(lambda x,y: x+y, a,b))
print(res) # [11, 22, 33]

小对比:map(lambda x:x*2, arr) VS [x*2 for x in arr]

简单类型转换(int、str)优先map;带判断、多层循环的复杂逻辑,列表推导式可读性更强。

实战清洗脏字符串

拿到带引号、空格的杂乱文本,一行清洗转换:

str1 = ' "11", "22", "33", "44" '
resa = list(map(lambda s: int(s.strip(' "')), str1.split(',')))
print(resa) # [11,22,33,44]

四、filter() 过滤器:留下满足条件的数据

filter(判断函数, 可迭代对象)

规则:判断函数返回True → 保留元素;返回False → 丢弃元素

同样返回迭代器,需要list转换。

需求:筛选大于5的数字

nums = [1,3,6,8,2,9]
原生循环
res = []
for n in nums:
if n > 5:
res.append(n)
filter + lambda一行搞定
res = list(filter(lambda x: x > 5, nums))
print(res) # [6,8,9]

五、组合使用小思路(拓展)

高阶函数最大魅力是链式搭配,举个例子:数字列表 → 筛选大于2 → 平方 → 从小到大排序

nums = [1,2,3,4,5]
result = sorted(
    map(lambda x:x**2, filter(lambda x:x>2, nums)))
print(result) # [9,16,25]

提醒:链式太深可读性崩盘的时候,果断拆开写,不要盲目追求一行代码!

六、避坑总结(新手高频踩雷点)

  1. lambda只能写单行表达式,不能使用多行代码、赋值语句;
  2. sorted产生新列表,不会修改原数据;
  3. map、filter返回迭代器,打印看不到内容,记得list()转换;
  4. map多序列匹配时,短列表截断长列表;
  5. key传函数对象!不要写成 key=func(),多加括号直接传函数返回值,直接报错;
  6. 不要滥用lambda,超过一层逻辑,命名函数def更加清晰。

更多推荐