簡體   English   中英

Python:創建一個包含 n 個列表的列表的最快方法

[英]Python: fastest way to create a list of n lists

所以我想知道如何最好地創建一個空白列表列表:

[[],[],[]...]

由於 Python 在內存中處理列表的方式,這不起作用:

[[]]*n

這確實創建了[[],[],...]但每個元素都是同一個列表:

d = [[]]*n
d[0].append(1)
#[[1],[1],...]

類似於列表理解的工作:

d = [[] for x in xrange(0,n)]

但這使用 Python VM 進行循環。 有什么方法可以使用隱式循環(利用它是用 C 編寫的)?

d = []
map(lambda n: d.append([]),xrange(0,10))

這實際上更慢。 :(

可能是唯一比

d = [[] for x in xrange(n)]

from itertools import repeat
d = [[] for i in repeat(None, n)]

它不必在每次迭代中都創建一個新的int對象,並且在我的機器上快了大約 15%。

編輯:使用 NumPy,您可以避免使用 Python 循環

d = numpy.empty((n, 0)).tolist()

但這實際上比列表理解慢 2.5 倍。

這里有兩種方法,一種簡單而簡單(和概念化),另一種更正式,可以在閱讀數據集后在各種情況下進行擴展。

方法一:概念

X2=[]
X1=[1,2,3]
X2.append(X1)
X3=[4,5,6]
X2.append(X3)
X2 thus has [[1,2,3],[4,5,6]] ie a list of lists. 

方法 2:形式化和可擴展

另一種將列表存儲為不同數字列表的優雅方式 - 它從文件中讀取。 (這里的文件有數據集 train)Train 是一個數據集,比如 50 行和 20 列。 IE。 Train[0] 給我 csv 文件的第一行,train[1] 給我第二行,依此類推。 我有興趣將具有 50 行的數據集作為一個列表分開,除了 0 列,這是我在此處解釋的變量,因此必須從原始火車數據集中刪除,然后逐個放大列表 - 即列表的列表. 這是執行此操作的代碼。

請注意,我在內循環中從“1”讀取,因為我只對解釋變量感興趣。 我在另一個循環中重新初始化 X1=[] ,否則 X2.append([0:(len(train[0])-1)]) 將一遍又一遍地重寫 X1 - 除了它更有效的內存。

X2=[]
for j in range(0,len(train)):
    X1=[]
    for k in range(1,len(train[0])):
        txt2=train[j][k]
        X1.append(txt2)
    X2.append(X1[0:(len(train[0])-1)])

列表推導實際上比顯式循環更有效地實現(參見dis輸出示例函數),並且map方式必須在每次迭代時調用一個不透明的可調用對象,這會產生相當大的開銷。

無論如何, [[] for _dummy in xrange(n)]是正確的方法,並且其他各種方法之間的微小(如果存在的話)速度差異都不重要。 當然,除非你把大部分時間都花在這上面——但在這種情況下,你應該研究你的算法。 您多久創建一次這些列表?

要創建列表和列表列表,請使用以下語法

     x = [[] for i in range(10)]

這將創建一維列表並初始化它,將數字放入 [[number] 並將列表長度設置為范圍(長度)

  • 要創建列表列表,請使用以下語法。
    x = [[[0] for i in range(3)] for i in range(10)]

這將初始化具有 10*3 維度和值為 0 的列表列表

  • 訪問/操作元素
    x[1][5]=value

所以我做了一些速度比較以獲得最快的方式。 列表推導確實非常快。 接近的唯一方法是避免在構建列表期間執行字節碼。 我的第一次嘗試是以下方法,原則上似乎更快:

l = [[]]
for _ in range(n): l.extend(map(list,l))

(當然,生成長度為 2**n 的列表)根據 timeit,對於短列表和長(一百萬)列表,這種構造的速度是列表理解的兩倍。

我的第二次嘗試是使用 starmap 為我調用列表構造函數,有一個構造,它似乎以最快的速度運行列表構造函數,但仍然較慢,但只有很小的數量:

from itertools import starmap
l = list(starmap(list,[()]*(1<<n)))

有趣的是,執行時間表明最終的列表調用使星圖解決方案變慢,因為它的執行時間幾乎完全等於以下速度:

l = list([] for _ in range(1<<n))

當我意識到 list(()) 也會產生一個列表時,我的第三次嘗試來了,所以我嘗試了顯然很簡單的方法:

l = list(map(list, [()]*(1<<n)))

但這比星圖調用慢。

結論:對於速度狂人:請使用列表理解。 如果必須,只調用函數。 使用內置函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM