为什么在操作完成后可以访问列表推导变量?

时间:2013-05-17 15:17:45

标签: python list-comprehension

作为另一种体验的一部分,我在列表理解中遇到了问题。为了简单起见,如果我正在尝试以下代码:

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. 这不是内存泄漏吗?

2 个答案:

答案 0 :(得分:11)

因为在Python 2中,列表变量'泄漏'到周围的范围。列表理解的构建方式存在错误。

这已经针对dict和set comprehensions,生成器表达式进行了更正,并且在Python 3中也针对列表推导进行了更正。

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

答案 1 :(得分:7)

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

因为存在有效引用,所以对象k指向的(正确)不是垃圾回收。

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

在Python 2.x中,生成器表达式 do 有自己的作用域,但是,如果你想要这种行为,只需这样写:

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