将带字典的Python列表转换为一个字典的最快方法

将带字典的Python列表转换为一个字典的最快方法,python,python-2.7,dictionary,Python,Python 2.7,Dictionary,我已经将大量数据解析到包含字典的列表中 [{123123:[0.45, 0.4]},{2332:[0.1, 09]}] 我在这个列表中有将近800000条记录,我想从中找到一本字典: my_dict = {} for i in dict_list: for k,v in i.iteritems(): my_dict[k] = v 有没有更快的方法可以做到这一点 像这样使用字典理解 >>> dict_list = [{123123:[0.45, 0.4

我已经将大量数据解析到包含字典的列表中

[{123123:[0.45, 0.4]},{2332:[0.1, 09]}]
我在这个列表中有将近800000条记录,我想从中找到一本字典:

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

有没有更快的方法可以做到这一点

像这样使用字典理解

>>> 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迭代和修改dictionary对象更快。

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

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

使用update应该非常有效:

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个由唯一键组成的dict列表再次运行测试,它显示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的三个键,再次更新wins:

 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应该更快,如果您有多个键,那么update应该更快。

reduce
可能仍会对您有所帮助(尽管我之前的答案有误):


编辑:谢谢,@padraiccningham,您测试了我的东西(并且显示它不是很好,至少对于分离键来说是这样)

通过改变数据解析的方式,您可能会获得更好的收益。如果您从一开始就正确格式化数据,那么您将不需要执行任何操作。平均每个dict中有多少个键?在OP的代码中更新
my_dict
应该更快,因为它删除了Python for循环。我不知道还有“dict comprehension”。很高兴知道!!:)不过请注意,这并不能解释重复的密钥。或者更确切地说,它遵循后进先出语义;最后遇到的重复键的值将是该键处的值。如果这是一个可能性/问题,您将需要一个更复杂的解决方案。您能将简单的循环更新与列表理解结合起来计时吗?例如,
timeit[dic目录列表的我的目录更新(dic)]
?@MarcusMüller,
229 ms
在大数据集上。以这种方式使用列表comp可能也会遭到反对;)惊奇地发现它比“完整”循环慢;我假设列表理解会更快,因为python不需要为每次迭代检查范围——很高兴知道!
import operator
dict(reduce(operator.add, [dic.items() for dic in dictlist]))