发电机工作奇怪


a = [1, 2, 3]
b = (c for c in a if c in a)
a = [2, 3, 4]
print(list(b))

def d(expr):
    for c in expr:
        if c in expr:
            yield c

a1 = [1,2,3]
t = d(a1)
a1 = [2,3,4]
print(list(t))

输出:

[2, 3]
[1, 2, 3]

问题:1( 在第一个变体中,循环保留列表的旧值 ([1,2,3](,但条件表达式采用新列表 a([2,3,4](。2(我自己的生成器如何给我除了生成表达式之外的其他结果?

例如,我

替换了第一个示例的真实列表,我希望这会更清楚地说明我的第一个问题。

a = [1, 2, 3]
b = (c for c in [1,2,3] if c in [2, 3, 4])
a = [2, 3, 4]
print(list(b))

输出:

[2,3]

根据 PEP 289,我们可以按如下方式重写生成器表达式:

# b = (c for c in a if c in a)
def __gen(expr):
    for c in expr:
        if c in a:
            yield c
b = __gen(iter(a))

在这里,对 for 循环中使用的 [1, 2, 3] 的引用会立即捕获(当您创建 b 时(,但if c in a检查使用等于 [2, 3, 4] 的新全局a

另一方面,当您编写生成器函数时,a1 将传递给该函数并存储以供以后在 forif x in y 表达式中使用。分配a1 = [2, 3, 4]不起作用。

要使函数与生成器表达式执行相同的操作,您需要做的就是将if c in expr替换为 if c in a1

最新更新