GitHub上有个被点了2.3万星的代码片段,内容简单到可笑:用一行Python替代了别人写的七行循环。评论区最高赞是"我写了五年Python,今天才发现自己是个小丑"。
这不是段子。Stack Overflow 2023年开发者调查显示,67%的Python使用者承认自己的循环代码"可以写得更好",但不知道具体怎么做。问题出在起点——大多数人学循环时,老师教的是C语言的思维方式。
「for i in range(len(data))」是一种病
来看一个真实场景。你想打印一个列表里的所有元素。
新手写法是这样的:先算长度,再建索引,最后取值。三行代码,两个变量,一次越界风险。这种写法在Java里没毛病,在Python里属于"拿着冲锋枪当烧火棍"。
Guido van Rossum(Python之父)在设计这门语言时,有个核心执念:代码应该像伪代码一样可读。他为此拒绝了无数功能提案,却坚持保留了「for...in」这个从ABC语言借鉴来的结构。三十年后,这成了Python最被浪费的特性。
正确的打开方式只有一个单词的差距:
直接迭代对象本身,而不是它的索引。
「for item in data」对比「for i in range(len(data))」,行数从3行变1行,变量从2个变0个,心智负担从"跟踪索引"变成"关注数据"。这不是风格问题,是效率问题——人读代码的时间远超机器执行的时间。
enumerate():被80%的人用错的瑞士军刀
那什么时候真的需要索引?比如你要同时拿到元素和它的位置。
我见过最荒唐的写法:先写个range循环拿索引,再用索引去取元素。相当于为了查字典,先把目录抄一遍,再按目录找页码。Python标准库里有现成工具——enumerate(),把可迭代对象包装成"索引+元素"的对。
但这里有个细节陷阱。enumerate()默认从0开始计数,如果你需要1-based的序号(比如打印"第X条"),得手动传start参数。这个参数的存在感极低,官方文档里藏在第三段,导致无数人用「i+1」这种土办法硬凑。
更隐蔽的坑是性能直觉的欺骗。有人觉得「while i < len(data)」比for循环更快,因为"更接近底层"。实测数据打脸:CPython 3.11里,纯Python层面的循环结构差异,执行时间差距在5%以内,可读性的代价却实打实。
Raymond Hettinger(Python核心开发者)在PyCon演讲里说过一句狠话:「There must be a better way」——这句话应该刻在每个Python用户的显示器边框上。他指的不仅是语法糖,而是一种"让代码自己说话"的思维习惯。
zip()的隐藏玩法:并行迭代不需要索引
另一个高频误用场景:同时遍历两个列表。比如一个存名字,一个存分数,要配对输出。
新手的本能反应是用同一个索引去两个列表里取数据。代码写出来像在做体操:初始化i,判断边界,递增,取值,防越界。五个动作里,只有"取值"是业务逻辑,其余全是脚手架。
zip()的设计意图就是拆掉这些脚手架。它把多个可迭代对象"拉链"到一起,每次吐出一组对应位置的元素。两个列表变一个循环变量,三个列表也一样处理。如果长度不齐,zip()默认提前结束——这个行为常被误以为是bug,其实是 deliberate design(有意设计),避免静默的数据丢失。
需要按最长列表遍历?用itertools.zip_longest(),填充值自己指定。Python的标准库像个工具墙,多数人只用过锤子,不知道旁边就有电钻。
列表推导式:循环的终极压缩
如果循环的目的是生成一个新列表,事情可以变得更激进。
把一个列表的每个元素平方,存成新列表。传统写法:初始化空列表,for循环,append,return。四行,一个临时变量,一次函数调用开销。
列表推导式把这四行压成一行:「[x**2 for x in data]」。语法上是个表达式,可以嵌套在任何需要列表的地方。速度上也有优势——CPython对推导式有专门的字节码优化,比等效的for循环快15%-30%。
但压缩有代价。当逻辑超过一层嵌套,或者需要副作用操作(比如打印),推导式会变得难以阅读。Google的Python风格指南明确建议:嵌套超过两层时,回退到普通循环。优雅的前提是可控的复杂度。
字典和集合也有对应的推导式语法,结构几乎一样。掌握这个模式,相当于解锁了Python的"批量操作"接口,代码密度能再上一个台阶。
回到开头那个2.3万星的代码片段。作者最后补了一句:「我统计了自己的项目,用这些技巧重构后,循环相关代码减少了62%」。不是性能提升,是删掉的行数——这些行原本存在,只是为了安抚你从C语言带来的肌肉记忆。
你最近一次写「range(len(」是什么时候?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.