为什么重新定义生成器中使用的变量会产生奇怪的结果?
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
被延迟评估,这就是为什么你已经可以引用一个尚未定义的变量
我的一个朋友问我这段代码:
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
被延迟评估,这就是为什么你已经可以引用一个尚未定义的变量