发电机工作奇怪

时间:2018-01-19 15:12:07

标签: python generator

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]

1 个答案:

答案 0 :(得分: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))

此处,我们会立即(当您创建[1, 2, 3]时)捕获用于for循环的b引用,但if c in a检查会使用新的全局a等于[2, 3, 4]

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

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