[英]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.