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

Blu*_*ice 3 python list-comprehension

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

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

Mar*_*ers 11

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

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

这不是内存泄漏.这只是变量范围内的错误.

  • 结论是让他们表现得像'for`循环的决定是错误的:-)结果是混淆了人,行为被改变了. (4认同)

kin*_*all 7

不,这不是内存泄漏,因为通常会定义该术语.在Python 2.x中,列表理解是不是一个单独的范围,让您在列表解析中使用变量是包含它的功能范围.通过k 列表理解之前设置,您可以轻松地看到这一点; listcomp会破坏它.

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

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

在Python 2.x中,生成器表达式确实有自己的作用域,所以如果你想要那个行为,就这样写它:

m = list(k**2 for k in range(7))
Run Code Online (Sandbox Code Playgroud)