如何在 Python 中建立具有特定大小的列表

  1. 為列表預分配儲存
  2. 為其他順序資料結構預分配儲存

當程式設計師提前知道元素數量時,為列表或陣列預分配儲存空間是程式設計師經常用地方式。

C++ 和 Java 不同,在 Python 中,你必須使用一些值初始化所有預分配的儲存。通常情況下,開發人員使用假值用於此目的,如 None''False0

Python 提供了幾種建立固定大小列表的方法,每種方法都有不同的效能特徵。

為了比較不同方法的效能,我們將使用 Python 的標準模組 timeit。它提供了一種方便的方法來測量一小段 Python 程式碼的執行時間。

為列表預分配儲存

第一個也是最快的方法,就是使用*運算子,它將列表重複指定的次數。

>>> [None] * 10
[None, None, None, None, None, None, None, None, None, None]

一百萬次迭代(timeit 的預設迭代值)大約需要 117 毫秒。

>>> timeit("[None] * 10")
0.11655918900214601

另一種方法是將 range 內建函式與列表推導式一起使用。

>>> [None for _ in range(10)]
[None, None, None, None, None, None, None, None, None, None]

它慢了將近六倍,每百萬次迭代需要 612 毫秒的時間。

>>> timeit("[None for _ in range(10)]")
0.6115895550028654

第三種方法是 list.append()for 迴圈一起使用。

>>> a = []
>>> for _ in range(10):
...   a.append(None)
...
>>> a
[None, None, None, None, None, None, None, None, None, None]

使用迴圈是最慢的方法,需要 842 毫秒才能完成一百萬次迭代。

>>> timeit("for _ in range(10): a.append(None)", setup="a=[]")
0.8420009529945673

為其他順序資料結構預分配儲存

由於你要為順序資料結構預先分配儲存空間,因此使用 array 內建資料結構而不是列表可能更有意義。

>>> from array import array
>>> array('i',(0,)*10)
array('i', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

如下所示,此方法僅次於 [None] * 10

>>> timeit("array('i',(0,)*10)", setup="from array import array")
0.4557597979946877

讓我們將上述純 Python 方法與 NumPy 用於科學計算的 Python 庫進行比較。

>>> from numpy import empty
>>> empty(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

NumPy 方法每百萬次迭代需要 589 毫秒。

>>> timeit("empty(10)", setup="from numpy import empty")
0.5890094790011062

但是,對於更大量的列表,NumPy 方法將更快。

>>> timeit("[None]*10000")
16.059584009999526
>>> timeit("empty(10000)", setup="from numpy import empty")
1.1065983309963485

結論是,對於小地列表來說,最好使用 [None] * 10,但在處理更大量的順序資料時切換到 NumPy 的 empty()

相關文章 - Python List

  • 在 Python 中找到列表中元素的索引
  • Python 列表方法 append 和 extend 之間有什麼區別