python - 为什么将列表初始化为空而不是具有预定大小是 Pythonic 的?

标签 python arrays list optimization

我的问题的简短版本:为什么 Python 中的常见做法是初始化一个空列表,即使列表的大小可能会多次更改,如下所示:

arr = []
for i in range(10):
   arr.append(i)

迭代地更改数组的大小在计算上不是很昂贵吗?

我的问题的长版本:我习惯使用 MATLAB,并且对 Python 相对较新。当我想要创建一个数组时,MATLAB 中的常见做法是初始化一个适当大小的零数组,然后用您想要的元素替换该数组的元素。这是因为在 MATLAB 中迭代更改数组大小的计算成本很高。 Python 有什么办法可以避免这种开支吗?当我看到人们在这个网站上回答涉及预初始化要添加到的列表的 Python 问题时,他们总是创建一个空列表,然后更改大小,我一直认为这是低效的。

最佳答案

Python 不会将列表逐一增长。它总是分配大块。 block 大小取决于列表的大小。因此,当列表变大时,预分配的空间也会变大。

例如,如果您执行 1000 万次追加,它会执行大约 100 次分配,即增加列表的步骤。

如果你从一个空列表开始,并通过一次附加一个元素来增长它,你会得到以下步骤,实际分配新的内存:

 list size:  allocations
        10:   3
       100:  10
      1000:  27
     10000:  46
    100000:  65
   1000000:  85
  10000000: 104

MATLAB 数组与 NumPy 数组更具可比性。这些数组的大小是固定的,逐步增长它们的成本非常昂贵。

关于python - 为什么将列表初始化为空而不是具有预定大小是 Pythonic 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47785229/

相关文章:

javascript - 如何根据字符串在每个元素中的位置对 PHP 数组进行排序?

c# - 数组排序效率...初学者需要指点

Python 与父 shell 环境一起工作

python - Python 中的目录统计信息

php - php explode 并强制数组键从1开始而不是0

在给定谓词为真的元素之后拆分列表的 Pythonic 方法

PHP。使用 list() 和 every() 吗?

list - 如何在 tcl 中比较两个列表(其中包含字符和数字)?

python - 科学 : Convert RGB TIFF to grayscale TIFF and output it on Matplotlib

python - 从隐藏在多索引中的年份和月份创建日期时间