Python编译器是否会优化相同参数的连续两次函数调用?
Python列表推导式中函数重复调用的优化判断与解决方案
问题场景
用户的代码如下:
result = len([x for x in otherList if func(x) is not None and func(x).weekday == 3])
用户偏好这种写法,但担心func(x)因执行成本高会被调用两次——如果用普通for循环,会先把func(x)的结果存到变量fx中复用。想知道有没有简便方法判断编译器是否会优化这段代码,让func(x)只执行一次。
解答
明确:CPython默认不会做这种优化
Python主流解释器CPython不会自动优化这类重复函数调用,因为它无法确定func(x)每次调用的结果是否一致(比如函数可能带副作用、依赖外部状态等),会严格按照代码逻辑执行两次调用:先判断func(x) is not None,若为真,再调用func(x).weekday == 3。简便测试方法
写一个带调用计数的func,运行代码后查看计数就能验证:
call_count = 0 def func(x): global call_count call_count += 1 # 模拟原func逻辑,返回带weekday属性的对象或None if x % 2 == 0: class Dummy: weekday = 3 return Dummy() else: return None otherList = [1,2,3,4,5] result = len([x for x in otherList if func(x) is not None and func(x).weekday == 3]) print(call_count) # 输出为6:符合条件的2、4各调用2次,其余元素各调用1次,总1+2+1+2+1=6
从计数结果就能直接确认func(x)的调用次数。
- 更可靠的写法:避免重复调用
与其依赖不确定的优化,不如直接修改代码确保func(x)只执行一次,两种常用方式:
- 使用海象运算符(Python 3.8+):
result = len([x for x in otherList if (fx := func(x)) is not None and fx.weekday == 3])
- 用嵌套生成器表达式提前捕获结果:
result = len([x for x, fx in ((x, func(x)) for x in otherList) if fx is not None and fx.weekday == 3])
这两种写法都能保证每个x只调用一次func(x),逻辑清晰且不受解释器优化策略影响。
内容的提问来源于stack exchange,提问作者doublefelix
相关产品推荐
相关产品推荐

