为啥在 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() 会返回内存错误?的主要内容,如果未能解决你的问题,请参考以下文章