python - 我发现自己挥舞着列表理解锤

标签 python list-comprehension

... 并且每个 for 循环看起来都像是一个列表推导式。

代替:

for stuff in all_stuff:
    do(stuff)

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

[ do(stuff) for stuff in all_stuff ]

这是在 list-comp how-to's 上发现的常见模式. 1) 好的,没什么大不了的吧?错误。 2) 这不能只是代码风格吗? super 错。

1) 是的,那是错误的。正如 NiklasB 指出的那样,HowTos 的目的是建立一个新列表。

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

我没有记住这些操作方法主要是基于命令行的。在我的团队对我大吼大叫,想知道我到底为什么要建立大量列表然后放弃它们之后,我想到我可能会引入一个与内存相关的主要错误。

所以这是我的问题。如果我要在一个运行时间很长的过程中执行此操作,其中会消耗大量数据,那么这个“列表”是否会继续消耗我的内存直到放手?垃圾收集器什么时候会收回内存?这个列表内置的作用域丢失后?

我猜是的,它会一直消耗我的内存。我不知道 python 垃圾收集器是如何工作的,但我敢说这个列表将一直存在,直到在 all_stuff 上调用最后一个 next 之后。

编辑。

我的问题的本质被传达得更清晰了 in this question (感谢尼克拉斯的链接)

最佳答案

If I were to do this in a very long running process, where lots of data was being consumed, would this "list" just continue consuming my memory until let go?

当然。

When will the garbage collector claim the memory back? After the scope this list is built in is lost?

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

感谢 Karl 指出,由于 CPython 使用的复杂内存管理机制,这意味着在那之后内存会立即返回给操作系统。

I don't know how the python garbage collector works, but I would venture to say that this list will exist until after the last next is called on all_stuff.

我不认为任何垃圾收集器都是这样工作的。通常他们会标记并清除,因此在垃圾收集列表之前可能需要相当长的时间。

This is a common pattern found on list-comp how-to's.

绝对不是。关键是你迭代列表的目的是对每个项目做一些事情(do 被称为 side-effects )。在 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

也许你会同意这个循环完全没有意义,因为它什么都不做,这与构建列表的理解相反。在您的示例中,情况恰恰相反:理解完全没有意义,因为您不需要列表!您可以在 related question 上找到有关该问题的更多信息。

顺便说一下,如果您真的想在一行中编写该循环,请使用像 deque.extend 这样的生成器使用者。不过,在这个简单示例中,这将比原始 for 循环稍慢:

>>> from collections import deque
>>> consume = deque(maxlen=0).extend
>>> consume(do(stuff) for stuff in all_stuff)

关于python - 我发现自己挥舞着列表理解锤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9746098/

相关文章:

python - 在Python中将逗号分隔的序列从DataFrame读取为字符串

python - 如何在 python 中创建伸缩术语集?

python - 如何使用理解列表创建包含 lambda 表达式的字典?

python - 为什么 itertools.chain 比展平列表理解更快?

python列表理解在一次迭代中产生两个值

haskell - 整理 Haskell 中的列表理解

python - 如何使用 python 的列表推导式来执行以下 matlab 代码?

python - 无法为 Python 3.6 pip 安装 sklearn

python - numpy 数组到置换矩阵

python - (最简单)在同一台计算机上使用 Python 3.6 和 3.7 的方法?