我发现自己摆动了列表理解锤

sba*_*ell 8 python list-comprehension

......每个for-loop看起来都像列表理解.

代替:

for stuff in all_stuff:
    do(stuff)
Run Code Online (Sandbox Code Playgroud)

我在做(没有将列表分配给任何东西):

[ do(stuff) for stuff in all_stuff ]
Run Code Online (Sandbox Code Playgroud)

这是list-comp方法的常见模式.1)好的,没什么大不了的?错误. 2) 这不能只是代码风格吗?超级错了.

1)是的,这是错的.正如NiklasB所指出的那样,HowTos的目标是建立一个新的列表.

2)也许,但它不明显和明确,所以最好不要使用它.

我没有记住那些操作方法基本上是基于命令行的.在我的团队向我大吼之后,想知道为什么我要建立大量的列表然后让它们离开,我突然意识到我可能会引入一个与内存相关的重大错误.

所以这是我的问题.如果我是在一个长时间运行的过程中这样做的,那里正在消耗大量数据,那么这个"列表"会继续消耗我的内存直到放手吗?垃圾收集器什么时候会回忆起内存?内置此列表之后是​​否已丢失?

我的猜测是肯定的,它会继续消耗我的记忆力.我不知道python垃圾收集器是如何工作的,但我冒昧地说这个列表将存在,直到next调用最后一个all_stuff.

编辑.

我的问题的实质是更清洁的中继在这个问题 (感谢链接尼克拉斯)

Nik*_* B. 6

如果我是在一个长时间运行的过程中这样做的,那里正在消耗大量数据,那么这个"列表"会继续消耗我的内存直到放手吗?

绝对.

垃圾收集器什么时候会回忆起内存?内置此列表之后是​​否已丢失?

CPython使用引用计数,因此这是最可能的情况.其他实现的工作方式不同,所以不要指望它.

由于卡尔的指出,由于CPython中使用的复杂的内存管理机制,但这并不意味着,存储立即返回后的操作系统.

我不知道python垃圾收集器是如何工作的,但我冒昧地说这个列表将存在,直到在all_stuff上调用last last后.

我不认为任何垃圾收集器都是这样的.通常它们会进行标记和扫描,因此可能需要一段时间才能对列表进行垃圾回收.

这是list-comp方法的常见模式.

绝对不.关键是你迭代列表的目的是对每个项目做一些事情(do被称为副作用).在List-comp HOWTO的所有示例中,迭代列表以基于旧列表构建新列表.我们来看一个例子:

# list comp, creates the list [0,1,2,3,4,5,6,7,8,9]
[i for i in range(10)]

# loop, does nothing
for i in range(10):
    i  # meh, just an expression which doesn't have an effect
Run Code Online (Sandbox Code Playgroud)

也许你会同意这个循环是毫无意义的,因为它没有做任何事情,与构建列表的理解相反.在你的例子中,它是相反的:理解是完全没有意义的,因为你不需要列表!您可以在相关问题上找到有关该问题的更多信息

顺便说一句,如果你真的想在一行中编写该循环,请使用像这样的生成器消费者deque.extend.for在这个简单的例子中,这将比原始循环略慢,但是:

>>> from collections import deque
>>> consume = deque(maxlen=0).extend
>>> consume(do(stuff) for stuff in all_stuff)
Run Code Online (Sandbox Code Playgroud)