2016-11-30 56 views
2

我正在解決一個問題,其中我需要一個零列表,之後我必須更新列表中的一些值。現在我在腦海中有兩個選擇,我怎麼能做到這一點首先是做一個零列表,然後更新值,或者我創建一個字典,然後我更新值。列表與字典在Python中存儲零

列表方法:

l=[0]*n 

字典方法:

d={} 
for i in range(n): 
    d[i]=0 

我們複雜打造字典O(n),然後更新的關鍵是O(1)。但我不知道python如何使用上面的方法構建零列表。

假設n是大量的其中一個上面的方法將成爲這個任務的更好嗎?以及如何在Python中實現列表方法? 。此外,爲什麼上面的列表方法比創建零列表的列表理解方法更快?

+1

我建議你做一些實驗,打印運行時間並查看自動差異。 – Acepcs

+2

字典初始化更好:'dict.fromkeys(range(n),0)'。 –

+1

'l = [0] * n'只是'l = list .__ mul __([0],n)',但是使用了一種語言結構。序列類型通常實現'__mul__'用於重複它們。 –

回答

2

的訪問和更新,一旦你已經預先分配的順序將是大致相同的。

選擇一個對您的應用程序有意義的數據結構。在這種情況下,我建議列表,因爲它更自然地適合「由整數索引的序列」

原因[0] * n很快就是它可以一次性製作正確大小的列表,而不是不斷擴展列表中添加了更多元素。

1

使用timeit運行測試後:

import timeit 
timeit.repeat("[0]*1000", number=1000000) 
#[4.489016328923801, 4.459866205812087, 4.477892545204176] 

timeit.repeat("""d={} 
for i in range(1000): 
d[i]=0""", number=1000000) 
#[77.77789647192793, 77.88324065372811, 77.7300221235187] 

timeit.repeat("""x={};x.fromkeys(range(1000),0)""", number=1000000) 
#[53.62738158027423, 53.87422525293914, 53.50821399216625] 

正如你可以看到有兩種方法和第三個是更好之間,但沒有列出巨大的差異!原因是創建list與指定的大小比創建一個dictionary與迭代擴展它的速度太快。

+0

Try:python -mtimeit -s'x = {}''x.fromkeys(range(1000),0)' –

1

我認爲在這種情況下,你應該只使用列表中,除非你想訪問某些數據,而無需使用索引。

Python list是一個數組。它以一個特定的大小進行初始化,當它需要存儲比它的大小可容納的更多的項目時,它將所有東西都複製到一個新的數組中,並且複製是O(k),其中k是列表的當時大小。這個過程可能會發生很多次,直到列表的大小大於或等於n。但是,[0] * n只會創建正確大小的數組(即n),因此比從頭開始將列表更新爲正確的大小要快。

對於由列表理解創建,如果你的意思是這樣[0 for i in range(n)],我覺得從更新列表的大小受到所以它比較慢。

Python字典是哈希表的實現,並使用散列函數來計算關鍵的哈希值,當你插入一個新的鍵值對。散列函數本身的執行相對昂貴,字典也處理其他情況,如碰撞,這使得它更慢。因此,字典中的創建0應該是理論上最慢的。

1

collections.defaultdict如果您希望在保持初始值的更新過程中有很多元素不會更改(並且您不以某種方式依賴於KeyError),那麼這可能是一個更好的解決方案。只是

import collections 
d = collections.defaultdict(int) 

assert d[42] == 0 
d[43] = 1 
# ... 

要考慮的另一件事是array.array。如果您只想存儲一種類型的元素(計數),則可以使用它。它應該比列表更快一點,並且內存效率更高:

import array 
l = array.array('L', [0]) * n 
# use as list