<p>是的,在Python2.x中列出理解“泄漏”它们的变量,就像for循环一样。</p>
<p>回想起来,这被认为是一个错误,并且通过生成器表达式避免了这个错误。EDIT:As<a href="https://stackoverflow.com/questions/4198906/python-list-comprehension-rebind-names-even-after-scope-of-comprehension-is-thi/4199344#comment10208805_4199355">Matt B. notes</a>当set和dictionary comprehension语法从Python 3后移植时,也避免了这种情况。</p>
<p>列表理解的行为必须保持在Python 2中的状态,但在Python 3中它是完全固定的。</p>
<p>这意味着:</p>
<pre><code>list(x for x in a if x>32)
set(x//4 for x in a if x>32) # just another generator exp.
dict((x, x//16) for x in a if x>32) # yet another generator exp.
{x//4 for x in a if x>32} # 2.7+ syntax
{x: x//16 for x in a if x>32} # 2.7+ syntax
</code></pre>
<p>在以下情况下,<code>x</code>始终是表达式的本地:</p>
<pre><code>[x for x in a if x>32]
set([x//4 for x in a if x>32]) # just another list comp.
dict([(x, x//16) for x in a if x>32]) # yet another list comp.
</code></pre>
<p>在Python 2.x中,all将<code>x</code>变量泄漏到周围的作用域。</p>
<hr/>
<p><strong>Python 3.8的更新(?)</strong>:<a href="https://www.python.org/dev/peps/pep-0572/" rel="nofollow noreferrer">PEP 572</a>将引入<code>:=</code>赋值运算符,该运算符故意泄漏理解和生成器表达式之外的信息!它的动机基本上是2个用例:从早期终止的功能(如<code>any()</code>和<code>all()</code>)中捕获“见证”:</p>
<pre><code>if any((comment := line).startswith('#') for line in lines):
print("First comment:", comment)
else:
print("There are no comments")
</code></pre>
<p>以及更新可变状态:</p>
<pre><code>total = 0
partial_sums = [total := total + v for v in values]
</code></pre>
<p>请参见<a href="https://www.python.org/dev/peps/pep-0572/#appendix-b-rough-code-translations-for-comprehensions" rel="nofollow noreferrer">Appendix B</a>了解确切范围。变量在最接近的<code>def</code>或<code>lambda</code>中赋值,除非该函数声明它<code>nonlocal</code>或<code>global</code>。</p>