为啥在 Python 3.x 的循环中使用 list() 会返回内存错误?

Posted

技术标签:

【中文标题】为啥在 Python 3.x 的循环中使用 list() 会返回内存错误?【英文标题】:Why using list() inside a loop return memory error in Python 3.x?为什么在 Python 3.x 的循环中使用 list() 会返回内存错误? 【发布时间】:2020-12-29 04:14:28 【问题描述】:

我得到以下代码:

var = []
for i in range(0,len(code_list)-11):
        
        sorted_list = sorted(code_list[i:i+10]) 
        minmax_list = list(range(min(sorted_list), max(sorted_list)+1))
        
        if (sorted_list == minmax_list):
            var = var+lista_ordenada

code_list 太大时,会返回内存错误。 但是,当替换为以下内容时:

var = []
for i in range(0,len(code_list)-11):
        
        sorted_list = sorted(code_list[i:i+10]) 
        minmax_list = np.arange(min(sorted_list), max(sorted_list)+1, 1).tolist()
        
        if (sorted_list == minmax_list):
            var = var+lista_ordenada

例程成功结束。有谁知道原因吗?

提前致谢!

【问题讨论】:

【参考方案1】:

tolist() 会将所有数据转换为 python 标准库类型。它还知道它是一个 numpy 数组,并且可以访问高度优化的后备数组。

list 只是使用迭代器来添加所有元素,因此速度要慢得多,而且占用内存也更多。

【讨论】:

这并不能解释为什么list(some_array) 需要比some_array.tolist() 更多的内存,这只是解释了为什么some_list 需要比some_array 更多的内存 "list 只是使用迭代器来添加所有元素" 这似乎意味着列表无法知道它需要预先设置的长度,但它当然可以在它之前检查len(...)如果长度可用(用于range(...)),则开始并预分配。 @ArthurTacca 是的,确实,在 CPython 中,我相信使用了 iter(arg_to_list).__length_hint__() @GhandiFloss 根本没有解决这个问题。在这两种情况下,都会创建一个列表。那么为什么要创建一个 numpy.ndarray first 然后一个列表占用更少的内存(大概)另外:“如果你有一些 n 字节的数组,列表将是 n 字节”绝对不正确。该列表大致仍为96 + n *size_of_objects_in_list。如果它是从 numpy 数组创建的,它仍然是一个列表 @GhandiFloss 不,您根本没有解决我所说的任何问题。您意识到,列表仍将包含 python 对象,因此结果列表中的每个对象至少需要 16 个字节。 列表是从数组创建的并不重要

以上是关于为啥在 Python 3.x 的循环中使用 list() 会返回内存错误?的主要内容,如果未能解决你的问题,请参考以下文章

python学习7

为啥 Python 3.x 的 super() 有魔力?

为啥我在无限循环中休眠的 python 脚本停止运行?

为啥这个while循环在Python中永远不会停止

为啥我可以在 Python for 循环中对迭代器和序列使用相同的名称?

为啥python有两个不同的版本,并且语法规范啥的都不相通呢?