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

Python生成器表达式与自定义生成器执行差异及变量绑定疑问

Understanding Generator Expressions vs. Generator Functions in Python

Let's walk through your questions step by step—these examples highlight some tricky but crucial behavior in Python's generator implementation.

First Question: Why does the generator expression use old a for iteration but new a for condition checks?

In the first example:

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

Here's the breakdown:

  • Generator expressions have a special variable binding rule: The iterable in the for clause (a in for c in a) is evaluated immediately when the generator is created. So when b is defined, Python grabs a reference to the original [1,2,3] list and stores it for later iteration.
  • The condition check (if c in a) is lazy-evaluated—it doesn't resolve the variable a until the generator actually runs (when you call list(b)). By that time, a has been reassigned to [2,3,4], so each element from the original list is checked against this new list.

That's why we end up with elements 2 and 3: they're from the original list, and they exist in the new list.

Second Question: Why do custom generators behave differently?

Your custom generator function:

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))  # Output: [1, 2, 3]

The key difference here is parameter passing:

  • When you call d(a1), Python evaluates a1 immediately and passes a reference to the original [1,2,3] list into the function as the expr parameter.
  • Inside the generator, both for c in expr and if c in expr refer to this fixed expr parameter (the original list), not the external a1 variable. Reassigning a1 later has no effect on the expr variable inside the generator.

So when you iterate over t, you're looping through the original list and checking membership against the same original list—all elements pass the check, hence the output [1,2,3].

Bonus: What happens when we replace a with literal lists?

In this modified example:

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))  # Output: [2,3]

Both [1,2,3] and [2,3,4] are literal lists, so they're evaluated immediately when the generator is created. They're independent of the a variable entirely—reassigning a later doesn't touch these lists. The generator iterates over [1,2,3] and checks against [2,3,4], which gives us the same result as the first example, but without the variable reassignment confusion.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:46:59