Python暴力求两数之和时嵌套for循环为何比内联推导快?
性能差异的核心原因
两者的执行逻辑存在本质区别,和是不是列表推导式语法糖无关:
brute_force_nested支持提前短路返回:只要在循环中找到第一组满足a + b == x的元素对,就会立刻返回True,不会继续遍历剩余的所有元素。你的测试用例里显然匹配的元素对出现得非常早,几乎跑了个开头就结束了,所以耗时只有几毫秒。- 列表推导式实现的
brute_force_inline必须遍历完全部元素:列表推导式会把所有满足条件的元素对全部收集起来生成完整列表,哪怕第一个元素就匹配成功,也会把两个列表的所有组合全部遍历完,生成所有符合条件的结果后才会转bool判断列表是否为空。如果S1、S2的量级稍大,遍历全部组合的开销会非常高,自然和前者出现数量级的耗时差,你测出的3秒对0.007秒的差距完全符合这个逻辑特征。
补充说明
很多人会有「列表推导式比普通循环快」的印象,这个结论成立的前提是两者都需要遍历完全部元素:列表推导式的循环是底层C实现的,比Python层的普通for循环开销更低。但你的场景存在提前终止的需求,普通循环可以主动提前返回,列表推导式本身不支持中途停止,这时候反而会更慢。
如果想用简洁的写法同时保留短路逻辑,可以改用生成器表达式+any(),写法如下:
@timing def brute_force_short(x, s1 : list, s2 : list) -> bool: return any(a + b == x for a in s2 for b in s1)
生成器是惰性求值的,只要找到第一个匹配的元素对就会立刻停止遍历,性能和手写的嵌套循环基本一致,甚至会略快一点。
内容的提问来源于stack exchange,提问作者ethanmorton
相关产品推荐
相关产品推荐

