为啥操作完成后可以访问列表理解变量? [复制]
Posted
技术标签:
【中文标题】为啥操作完成后可以访问列表理解变量? [复制]【英文标题】:Why the list comprehension variable is accessible after the operation is done? [duplicate]为什么操作完成后可以访问列表理解变量? [复制] 【发布时间】:2013-05-12 19:55:40 【问题描述】:作为另一种体验的一部分,我在列表理解中遇到了问题。简单地说,如果我正在尝试以下代码:
m = [ k**2 for k in range(7)]
print m
[0, 1, 4, 9, 16, 25, 36]
print k
6
-
我的问题是,python 如何在列表理解之外获得 k 的值?
为什么不收集 k 垃圾?
这不是内存泄漏吗?
【问题讨论】:
【参考方案1】:因为在 Python 2 中,列表变量“泄漏”到周围的范围。这是构建列表推导方式的错误。
这已针对 dict 和 set 推导、生成器表达式以及 Python 3 中的列表推导进行了更正。
这不是内存泄漏。这只是变量范围的错误。
【讨论】:
这实际上不是一个错误。这个想法是它的行为应该与等效的for
循环相同。 for
循环没有自己的范围,所以列表推导也没有。后来他们改变了主意。
结论是,让他们表现得像 for
循环的决定是错误的 :-) 结果让人们感到困惑,并且行为被改变了。【参考方案2】:
不,这不是通常定义的内存泄漏。在 Python 2.x 中,列表推导不是一个单独的范围,因此您在列表推导中使用的变量位于包含它的函数的范围内。通过设置k
before 列表理解,您可以轻松地看到这一点; listcomp 会破坏它。
由于存在有效引用,k
指向的对象(正确地)不会被垃圾回收。
在 Python 3.x 中,这已更改;所有的理解都会创建自己的作用域,并且不会“泄漏”到封闭的作用域中。
然而,在 Python 2.x 中,生成器表达式 确实 有自己的作用域,所以如果你想要这种行为,只需这样写:
m = list(k**2 for k in range(7))
【讨论】:
问题是如果你之前声明了变量 k 并且想在列表解析后使用它,k 的值就会改变。以上是关于为啥操作完成后可以访问列表理解变量? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥从类中访问类变量需要“自我”。在 Python 中? [复制]
为啥即使使用 setlocal enabledelayedexpansion 也无法访问 for 循环(批处理文件)中的局部变量? [复制]