2012-09-22 28 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