将带字典的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]))