平时咱们用 Python 处理数据的时候,经常会碰到一些重复又繁琐的操作,比如分批处理大文件、合并不同长度的列表、生成参数组合等等。这时候 Python 自带的 itertools 模块就派上大用场了,里面藏着不少好用的函数,能帮咱们把代码写得又快又漂亮。今天就给大家扒一扒 5 个特别实用的 "宝藏函数",每个都带简单好懂的案例,保证代码能直接跑起来!
一、batched:按需分批处理数据,内存友好的 "大块头救星"
功能讲解
这个函数是 Python 3.12 之后新增的,专门用来处理大规模数据。啥意思呢?比如你有 10 万个数据,要是一股脑全塞进内存里,电脑可能直接卡住。batched 能让你自己定一个批次大小,比如每 100 个数据处理一次,每次只在内存里存这 100 个,处理完一批再取下一批,就像吃自助餐一样,分批次拿食物,不把胃撑坏。特别适合处理数据流、大文件读取这种场景。
案例演示
比如咱们生成 1 到 10 这 10 个数,想每 3 个分一批处理:
from itertools import batched
numbers = range(1, 11)
for batch in batched(numbers, 3):
print(list(batch))
运行结果:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10] # 最后一批不够3个,就剩10自己
要是处理更大的数据,比如模拟一个无限数据流(当然实际会加停止条件),每次处理 100 个,也不会占太多内存。比如从文件里逐行读取,每 100 行处理一次,写法差不多,把 range 换成文件读取的迭代器就行。
适用场景
-
处理几 GB 的大文件,逐批读取处理
-
网络数据流,比如实时接收的数据分批次解析
-
避免一次性加载大量数据导致内存爆炸
二、zip_longest:专治 "长短不一" 的列表合并,想怎么补就怎么补
功能讲解
普通的 zip 函数大家都用过,比如 zip ([1,2],[a,b,c]),结果只会到短的那个列表结束,也就是 [(1,'a'),(2,'b')],第三个 'c' 就被扔掉了。但现实中经常遇到两个列表长度不一样的情况,比如统计两个部门的员工绩效,一个部门 5 人,一个部门 3 人,想把每个人的绩效一一对应,短的部门没数据的地方就需要补个默认值,比如补个 0 或者 ' 无'。zip_longest 就支持自定义填充值,让长的列表也能对齐,不会漏掉任何一个数据。
案例对比
输入列表 1 | 输入列表 2 | 普通 zip 结果 | zip_longest (填充 None) | zip_longest (填充 '-') |
---|---|---|---|---|
[1, 2] | ['a', 'b', 'c'] | [(1, 'a'), (2, 'b')] | [(1, 'a'), (2, 'b'), (None, 'c')] | [(1, 'a'), (2, 'b'), ('-', 'c')] |
具体代码:
from itertools import zip_longest
list1 = [1, 2]
list2 = ['a', 'b', 'c']
# 普通zip
print("普通zip结果:", list(zip(list1, list2)))
# zip_longest默认填充None
print("zip_longest填充None:", list(zip_longest(list1, list2)))
# 自定义填充'-'
print("zip_longest填充'-':", list(zip_longest(list1, list2, fillvalue='-')))
运行结果:
普通zip结果: [(1, 'a'), (2, 'b')]
zip_longest填充None: [(1, 'a'), (2, 'b'), (None, 'c')]
zip_longest填充'-': [(1, 'a'), (2, 'b'), ('-', 'c')]
适用场景
-
合并两个长度不同的配置文件数据
-
对齐日志中的不同步事件记录
-
处理 Excel 中两列数据长度不一致的情况
三、product:一行代码生成所有组合,告别嵌套循环的噩梦
功能讲解
比如你想生成颜色和尺寸的所有组合,颜色有 [' 红 ',' 蓝 '],尺寸有 ['S','M','L'],正常得写两层循环,外层颜色,内层尺寸,然后把每个组合存起来。但 product 能直接帮你生成笛卡尔积,也就是所有可能的组合,一行代码搞定,再也不用写一堆 for 循环嵌套了。特别适合枚举参数组合、生成测试用例、配置项排列等场景。
案例演示
生成颜色和尺寸的所有组合:
from itertools import product
colors = ['红', '蓝']
sizes = ['S', 'M', 'L']
for combo in product(colors, sizes):
print(combo)
运行结果:
('红', 'S')
('红', 'M')
('红', 'L')
('蓝', 'S')
('蓝', 'M')
('蓝', 'L')
如果是三个列表的组合,比如再加一个材质 [' 棉 ',' 麻 '],也是一样的写法,product (colors, sizes, materials),会生成三层组合,代码依然简洁。
适用场景
-
生成算法测试的所有参数组合
-
电商平台商品的规格组合(颜色 + 尺寸 + 材质)
-
枚举所有可能的配置项组合
四、starmap:多参数函数的 "解包神器",告别手动拆元组
功能讲解
普通的 map 函数只能处理单参数的函数,比如 map (lambda x: x*2, [1,2,3])。但如果你的函数需要两个参数,比如计算 x 的 y 次方,函数是 pow (x,y),而你的数据是一个列表 of 元组,比如 [(2,3),(3,2),(4,2)],这时候普通 map 就不行了,因为它传进去的是整个元组,比如第一个参数是 (2,3),而 pow 需要两个参数。这时候 starmap 就派上用场了,它会自动把元组解包成单个参数,也就是把 (2,3) 拆成 2 和 3 传给 pow,这样就能正确计算了。
案例对比
普通 map 报错写法 vs starmap 正确写法:
from itertools import starmap
# 普通map会报错,因为传的是元组,pow需要两个参数
# print(list(map(pow, [(2,3),(3,2),(4,2)]))) # 会报错:TypeError: pow expected 2 arguments, got 1
# starmap正确写法
print(list(starmap(pow, [(2,3),(3,2),(4,2)])))
运行结果:
[8, 9, 16]
再举个例子,计算多个点到原点的距离,点坐标是 (x,y),函数是计算√(x²+y²),用 starmap:
import math
points = [(3,4), (0,0), (6,8)]
distances = list(starmap(lambda x,y: math.sqrt(x**2 + y**2), points))
print(distances)
运行结果:
[5.0, 0.0, 10.0]
适用场景
-
处理需要多参数的函数,数据以元组形式存储
-
简化多参数循环处理,让代码更简洁
-
替代手动拆元组的繁琐操作
五、groupby:按条件分组数据,先排序再分组的 "数据归类大师"
功能讲解
groupby 可以把数据按照某个键分组,比如按字符串长度分组,按年龄分段分组,按日志中的错误类型分组等等。不过要注意,它要求数据是按照分组键排好序的,因为它是按照连续相同的键来分组的。比如先把列表按长度排序,然后相同长度的就会连续出现,groupby 就能把它们分到一组。每组会有一个键(比如长度 5),和对应的迭代器,里面是所有该键的数据。
案例演示
按字符串长度分组:
from itertools import groupby
from operator import itemgetter # 辅助排序的工具
# 先定义数据,然后按长度排序
words = ['apple', 'banana', 'cat', 'dog', 'elephant', 'fish']
# 按长度排序,这样相同长度的会连续
words_sorted = sorted(words, key=len)
# 分组
for length, group in groupby(words_sorted, key=len):
print(f"长度为{length}的单词:{list(group)}")
运行结果:
长度为3的单词:['cat', 'dog', 'fish']
长度为5的单词:['apple']
长度为6的单词:['banana']
长度为8的单词:['elephant']
这里 key 参数可以是一个函数,比如 len,也可以是自定义的函数,比如按首字母分组,就需要先按首字母排序,然后 key=lambda x: x [0]。
再举个按数值范围分组的例子,比如学生成绩按分数段(60 以下,60-80,80 以上)分组:
scores = [75, 88, 55, 90, 62, 70, 45]
# 先排序,然后定义分组函数
scores_sorted = sorted(scores)
def get_group(score):
if score < 60:
return '不及格'
elif score < 80:
return '中等'
else:
return '优秀'
for group, items in groupby(scores_sorted, key=get_group):
print(f"{group}:{list(items)}")
运行结果:
不及格:[45, 55]
中等:[62, 70, 75]
优秀:[88, 90]
适用场景
-
日志分析,按错误类型分组统计次数
-
电商数据,按商品类别分组计算销量
-
数据清洗,按某个属性分组处理缺失值
总结:5 个函数各显神通,按需选择效率高
函数名 | 核心功能 | 必备条件 / 注意点 | 典型场景 |
---|---|---|---|
batched | 分批处理数据,控制内存占用 | Python 3.12 + 版本 | 大文件处理、数据流解析 |
zip_longest | 对齐不同长度列表,支持填充缺失值 | 需导入 itertools | 合并长短不一的配置数据 |
product | 生成所有组合,笛卡尔积 | 简单参数枚举 | 配置项组合、测试用例生成 |
starmap | 处理多参数函数,自动解包元组 | 数据以元组形式存储 | 多参数函数批量应用 |
groupby | 按键分组数据,需先排序 | 数据需按分组键排序 | 日志分组、数据归类 |
这几个函数都是 itertools 里的 "精兵强将",学会之后能省掉很多重复代码,尤其是处理大规模数据或者复杂组合时,优势特别明显。建议大家把代码案例自己敲一遍,试试不同的参数,感受一下它们的灵活性。下次遇到类似的数据处理问题,就能第一时间想到合适的工具,再也不用对着代码发愁啦!