Python3中遍历map的最快方式?循环为何比map实现快近一倍
为什么你的
map版本更慢,以及Python3遍历map迭代器的最快方式 嘿,这个问题问到点子上了!先拆解下你遇到的情况:你把字典按值分组的循环实现改成map版本后,速度慢了将近一倍,核心原因其实不是遍历map的方式,而是map本身就不适合用来做这种带副作用的操作——比如修改外部字典。不过先回到你的核心问题:Python3里遍历map返回的迭代器,最快的方式是什么?
先搞懂为什么你的map版本慢
你用any(map(lambda i: ...))的方式触发map迭代,这里有两个额外开销:
lambda的函数调用开销:每次迭代都要调用一次匿名函数,而原生循环里直接操作字典,没有这个函数调用的额外成本。any()的判断开销:any()会检查每个lambda的返回值(append()返回None,所以any()会遍历完所有元素,但每次都要做一次“是否为真”的判断,这又是额外开销)。
而且map的设计初衷是纯函数式转换——把一个序列的每个元素转换成另一个值,而不是用来执行修改外部状态的副作用操作。用它来做字典分组,本身就是用错了工具。
Python3遍历map迭代器的最快方式
如果一定要用map,最快的遍历方式就是直接用for循环迭代map返回的迭代器。因为for循环在Python底层是高度优化的,没有额外的判断或函数调用开销。比如把你的代码改成这样:
files = {'Code.py': 'Stan', 'Output.txt': 'Randy', 'Input.txt': 'Randy'} mapped = {} # 用for循环直接遍历map迭代器 for v, k in map(lambda kv: (kv[1], kv[0]), files.items()): mapped.setdefault(v, []).append(k)
这个版本的速度会比你用any()的版本快很多,但依然会比原生循环慢——因为还是有lambda的函数调用开销。
性能最优的字典分组写法
如果你的目标是按值分组字典,原生for循环(或者结合collections.defaultdict)才是最快的选择:
原生循环写法(你的原始版本)
mapped = {} for k, v in files.items(): mapped.setdefault(v, []).append(k)
用defaultdict简化(速度和原生循环差不多)
from collections import defaultdict mapped = defaultdict(list) for k, v in files.items(): mapped[v].append(k)
用timeit测试的话,这两个版本的速度基本一致,而且都比任何map版本快一倍左右——因为没有额外的函数调用开销,直接操作字典是Python里最底层、最优化的操作之一。
总结一下
- 遍历
map迭代器最快的方式是直接用for循环,避免用any()/all()这类带判断逻辑的函数触发迭代。 - 但如果是做字典分组这类带副作用的操作,
map不是合适的工具,原生循环或defaultdict才是性能最优的选择。
内容的提问来源于stack exchange,提问作者ThisGuyCantEven
相关产品推荐
相关产品推荐

