2012-09-22 51 views

回答

19

這取決於您使用的是哪個版本的Python。在Python 2中,some_dict.items()會創建一個新列表,這會佔用一些額外的時間並佔用額外的內存。另一方面,一旦列表被創建,它就是一個列表,並且在列表創建的開銷完成之後應該具有相同的性能特徵。

在Python 3中,some_dict.items()創建了一個視圖對象而不是一個列表,並且我預計創建和迭代items()會比Python 2更快,因爲不需要複製任何內容。但我預測迭代已經創建的視圖會比迭代已經創建的列表慢一點,因爲字典數據存儲有點稀疏,我相信沒有好的方法讓python避免遍歷每一個在詞典中的bin - 甚至是空的。

在Python 2,一些計時證實了我的直覺:

>>> some_dict = dict(zip(xrange(1000), reversed(xrange(1000)))) 
>>> some_list = zip(xrange(1000), xrange(1000)) 
>>> %timeit for t in some_list: t 
10000 loops, best of 3: 25.6 us per loop 
>>> %timeit for t in some_dict.items(): t 
10000 loops, best of 3: 57.3 us per loop 

遍歷items大約慢一倍。使用iteritems是一個稍微有點快......

>>> %timeit for t in some_dict.iteritems(): t 
10000 loops, best of 3: 41.3 us per loop 

但是遍歷清單本身基本上是一樣的迭代比任何其他列表:

>>> some_dict_list = some_dict.items() 
>>> %timeit for t in some_dict_list: t 
10000 loops, best of 3: 26.1 us per loop 

Python 3中可以創建和迭代速度items (與上面的57.3 us相比):

>>> some_dict = dict(zip(range(1000), reversed(range(1000)))) 
>>> %timeit for t in some_dict.items(): t  
10000 loops, best of 3: 33.4 us per loop 

但是創建視圖的時間可以忽略不計;迭代實際上比列表慢。

>>> some_list = list(zip(range(1000), reversed(range(1000)))) 
>>> some_dict_view = some_dict.items() 
>>> %timeit for t in some_list: t 
10000 loops, best of 3: 18.6 us per loop 
>>> %timeit for t in some_dict_view: t 
10000 loops, best of 3: 33.3 us per loop 

這意味着,在Python 3,如果你想遍歷項目多次在一本字典和性能是至關重要的,你可以通過緩存視圖列表獲得30%的速度提升。

>>> some_list = list(some_dict_view) 
>>> %timeit for t in some_list: t 
100000 loops, best of 3: 18.6 us per loop 
6

一個基準測試顯示迭代列表的速度肯定會更快。

def iterlist(list_): 
    i = 0 
    for _ in list_: 
     i += 1 
    return i 

def iterdict(dict_): 
    i = 0 
    for _ in dict_.iteritems(): 
     i += 1 
    return i 

def noiterdict(dict_): 
    i = 0 
    for _ in dict_.items(): 
     i += 1 
    return i 

list_ = range(1000000) 
dict_ = dict(zip(range(1000000), range(1000000))) 

測試與IPython的關於Python 2.7(Kubuntu的):

%timeit iterlist(list_) 
10 loops, best of 3: 28.5 ms per loop 

%timeit iterdict(dict_) 
10 loops, best of 3: 39.7 ms per loop 

%timeit noiterdict(dict_) 
10 loops, best of 3: 86.1 ms per loop 
0

雖然通過some_list迭代爲2x加速比some_dict.items(),而是由索引通過some_list迭代幾乎是與由密鑰通過some_dict迭代。

K = 1000000 
some_dict = dict(zip(xrange(K), reversed(xrange(K)))) 
some_list = zip(xrange(K), xrange(K)) 
%timeit for t in some_list: t 
10 loops, best of 3: 55.7 ms per loop 
%timeit for i in xrange(len(some_list)):some_list[i] 
10 loops, best of 3: 94 ms per loop 
%timeit for key in some_dict: some_dict[key] 
10 loops, best of 3: 115 ms per loop 
%timeit for i,t in enumerate(some_list): t 
10 loops, best of 3: 103 ms per loop