为啥操作完成后可以访问列表理解变量? [复制]

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 循环(批处理文件)中的局部变量? [复制]

为啥我能够从在同一对象的另一个实例上调用的方法访问一个实例的私有实例变量? [复制]

为啥我重命名后无法访问 pandas 中的列? [复制]

为啥在ios中重新打开会话后无法访问facebook好友列表