为什么重新定义生成器中使用的变量会产生奇怪的结果?

Why does redefining a variable used in a generator give strange results?

我的一个朋友问我这段代码:

array = [1, 8, 15]
gen = (x for x in array if array.count(x) > 0)
array = [2, 8, 22]
print(list(gen))

输出:

[8]

其他元素去哪儿了?

答案在生成器表达式的 PEP 中,特别是会话 Early Binding vs Late biding:

After much discussion, it was decided that the first (outermost) for-expression should be evaluated immediately and that the remaining expressions be evaluated when the generator is executed.

所以基本上 array 在:

x for x in array 

使用原始列表 [1, 8, 15] 进行评估(即立即),而另一个:

if array.count(x) > 0

在生成器执行时计算:

print(list(gen))

此时 array 引用了一个新列表 [2, 8, 22]

如果你给每个数组一个唯一的名字而不是重新绑定,这会变得更清楚array:

array1 = [1, 8, 15]
gen = (x for x in array1 if array2.count(x) > 0)
array2 = [2, 8, 22]
print(list(gen))

x for x in array1 在创建生成器时被评估,但是 if array2.count(x) > 0 被延迟评估,这就是为什么你已经可以引用一个尚未定义的变量