将带有字典的Python List转换为一个字典的最快方法

时间:2015-03-16 18:14:31

标签: python python-2.7 dictionary

我已将大量数据解析为包含词典的列表。

[{123123:[0.45, 0.4]},{2332:[0.1, 09]}]

我在此列表中有近800,000条记录,我想从中获取一个字典:

my_dict = {}
for i in dict_list:
    for k,v in i.iteritems():
        my_dict[k] = v

有没有更快的方法来做到这一点。

4 个答案:

答案 0 :(得分:4)

使用字典理解,就像这样

>>> dict_list = [{123123:[0.45, 0.4]},{2332:[0.1, 9]}]
>>> {key: item[key] for item in dict_list for key in item}
{123123: [0.45, 0.4], 2332: [0.1, 9]}

由于理解是用C代码完成的,所以它应该比用Python迭代和改变字典对象要快得多。

答案 1 :(得分:2)

使用更新应该非常有效:

my_dict = {}
for d in dict_list:
    my_dict.update(d)

您输入的一些时间:

In [13]: %%timeit
my_dict = {}
for d in dict_list:
    my_dict.update(d)
   ....: 
1000000 loops, best of 3: 557 ns per loop

In [14]: timeit {key: item[key] for item in dict_list for key in item}
1000000 loops, best of 3: 597 ns per loop

In [15]: %%timeit                                         
my_dict = {}
for i in dict_list:
    for k,v in i.iteritems():
        my_dict[k] = v
   ....: 
1000000 loops, best of 3: 664 ns per loop
In [16]: %%timeit
my_dict = {}
for d in dict_list:
    for k in d:
       my_dict[k] = d[k]
   ....: 
1000000 loops, best of 3: 626 ns per loop
In [17]: timeit dict(reduce(operator.add, [dic.items() for dic in  dict_list]))
1000000 loops, best of 3: 1.55 µs per loop

需要注意的一件事是,如果您有重复的密钥,那么每次最后都会覆盖您为特定密钥遇到的最后一个值时,将覆盖该值。

使用由唯一键组成的800000个dicts列表再次运行测试,它显示dict理解是最快的:

In [81]: dict_list = [{i:[1,2,3]} for i in xrange(800000)] 

In [82]: timeit {key: item[key] for item in dict_list for key in item} 
10 loops, best of 3: 165 ms per loop

In [83]: %%timeit                                                      
my_dict = {}
for d in dict_list:
    my_dict.update(d)
   ....: 
1 loops, best of 3: 215 ms per loop

In [84]: %%timeit
my_dict = {}
for d in dict_list:
    for k in d:
       my_dict[k] = d[k]
   ....: 
10 loops, best of 3: 198 ms per loop

In [85]: %%timeit                                                     
my_dict = {}
for i in dict_list:
    for k,v in i.iteritems():
        my_dict[k] = v
   ....: 
1 loops, best of 3: 226 ms per loop

只是为了验证两者产生相同的输出:

In [79]: my_dict = {}                                                 
for d in dict_list:
    my_dict.update(d)
   ....:    
In [115]: len(my_dict)
Out[115]: 2400000


In [80]: my_dict ==  {key: item[key] for item in dict_list for key in item}
Out[80]: True

最后每个dict使用三个键,更新再次获胜:

 In [108]: dict_list = [{i:[1000,2000,3000],i+800000:[1000,2000,3000],i+1700000:[1000,2000,3000]} for i in xrange(800000)]

In [109]: %%timeit
my_dict = {}
for i in dict_list:
    for k,v in i.iteritems():
        my_dict[k] = v
   .....: 
1 loops, best of 3: 468 ms per loop

In [110]: %%timeit
my_dict = {}
for d in dict_list:
    for k in d:              
       my_dict[k] = d[k]
   .....: 
1 loops, best of 3: 476 ms per loop

In [111]: timeit {key: item[key] for item in dict_list for key in item}
1 loops, best of 3: 448 ms per loop

In [112]: %%timeit                                                     
my_dict = {}
for d in dict_list:
    my_dict.update(d)
   .....: 
1 loops, best of 3: 328 ms per loop

所以似乎有更多的键有助于抵消调用更新的成本,所以如果你的输入有一个键,那么dict comp应该更快,如果你有多个键,那么更新应该是。

答案 2 :(得分:0)

正如其中一条评论所述,使用dict.update应该更容易,更快:

my_dict = {}
for d in dict_list:
    my_dict.update(d)

答案 3 :(得分:0)

reduce可能仍然可以帮到你(虽然我搞砸了我之前的回答):

import operator
dict(reduce(operator.add, [dic.items() for dic in dictlist]))
编辑:谢谢,@ padraicCunningham,测试我的东西(显示它不是那么好,至少对于分离键)