0
点赞
收藏
分享

微信扫一扫

Python 大神总结的5个迭代器函数

平时咱们用 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 里的 "精兵强将",学会之后能省掉很多重复代码,尤其是处理大规模数据或者复杂组合时,优势特别明显。建议大家把代码案例自己敲一遍,试试不同的参数,感受一下它们的灵活性。下次遇到类似的数据处理问题,就能第一时间想到合适的工具,再也不用对着代码发愁啦!

举报

相关推荐

0 条评论