You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)只执行一次。

解答

  1. 明确:CPython默认不会做这种优化
    Python主流解释器CPython不会自动优化这类重复函数调用,因为它无法确定func(x)每次调用的结果是否一致(比如函数可能带副作用、依赖外部状态等),会严格按照代码逻辑执行两次调用:先判断func(x) is not None,若为真,再调用func(x).weekday == 3。

  2. 简便测试方法
    写一个带调用计数的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)的调用次数。

  1. 更可靠的写法:避免重复调用
    与其依赖不确定的优化,不如直接修改代码确保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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:18:20