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

为什么重定义生成器使用的变量会得到不符合预期的运行结果?

Python生成器惰性求值与延迟绑定问题分析

首先给出问题中的代码:

array = [1, 8, 15]
gen = (x for x in array if array.count(x) > 0)
array = [2, 8, 22]
print(list(gen))
# 输出结果: [8]

核心原因

这个现象是Python生成器的两个特性共同导致的:

  • 生成器是惰性求值的:生成器定义时不会立刻执行内部逻辑,只有当迭代生成器(本例中调用list(gen))时,才会逐次执行过滤逻辑
  • 生成器内部的自由变量是延迟绑定的:变量的值只会在实际执行逻辑时才会获取,而非生成器定义时

代码执行步骤拆解

  1. 执行array = [1, 8, 15],变量array指向数组[1, 8, 15]
  2. 执行gen = (x for x in array if array.count(x) > 0)完成生成器定义:
    • for x in array这部分的可迭代对象会在生成器定义时立刻求值,因此生成器后续要迭代的元素固定为[1, 8, 15]三个
    • 过滤条件if array.count(x) > 0中的array属于自由变量,此时不会求值,只会在后续迭代时获取当前array的指向
  3. 执行array = [2, 8, 22],变量array改为指向新数组[2, 8, 22]
  4. 执行list(gen)迭代生成器,开始逐元素判断:
    • 迭代第一个元素x=1:查询当前array(即[2,8,22])中1的个数为0,不满足条件,被过滤
    • 迭代第二个元素x=8:查询当前array中8的个数为1,满足条件,保留
    • 迭代第三个元素x=15:查询当前array中15的个数为0,不满足条件,被过滤
      最终输出结果就只有[8],原数组的1和15都被过滤掉了。

拓展验证

如果把生成器改为列表推导式,会立刻执行所有逻辑,输出就会是[1, 8, 15],代码如下:

array = [1, 8, 15]
res = [x for x in array if array.count(x) > 0]
array = [2, 8, 22]
print(res)
# 输出结果: [1, 8, 15]

内容的提问来源于stack exchange,提问作者pickle rick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:45:04