2013-05-17 20 views
2

作为另一个体验的一部分,我在列表理解中遇到了一个问题。为了简单地说,如果我想下面的代码:为什么在操作完成后可以访问列表理解变量?

m = [ k**2 for k in range(7)] 
print m 
[0, 1, 4, 9, 16, 25, 36] 
print k 
6 
  1. 我的问题是,Python是如何能够获得k的值,列表理解么?
  2. 为什么k不是垃圾收集?
  3. 这不是内存泄漏吗?

回答

4

不,这不是内存泄漏,因为该术语通常是定义的。在Python 2.x中,列表理解不是一个单独的范围,因此您在列表理解中使用的变量位于包含它的函数的范围内。您可以通过在之前设置k列表来理解, listcomp将会破坏它。

由于存在有效的引用,因此指向的对象k(正确)未被垃圾收集。

在Python 3.x中,这被改变了;所有的理解都会创建自己的范围,并且不会“泄漏”到封闭范围内。

在Python 2.x中,生成器表达式有自己的范围,但是,如果你想要的行为,只是把它写这样的:

m = list(k**2 for k in range(7)) 
+0

问题是如果你之前已经声明变量k并且想在列表理解之后使用它,那么k的值会被改变。 – Blueice

9

因为在Python 2中,列表变量'泄漏'到周围的范围。这是列表理解建立的错误。

这已经纠正为字典和设置理解,生成器表达式,并在Python 3列表解析以及。

这不是内存泄漏。这只是变量范围中的一个错误。

+0

这实际上不是一个错误。这个想法是它的行为应该与'for'循环相同。 'for'循环没有自己的范围,所以也没有列出理解。他们后来改变了主意。 – kindall

+3

结论是让他们表现得像'for'循环的决定是错误的:-)结果是人们感到困惑,行为被改变了。 –

相关问题