python – 按键结合两个大字典 – 最快的方法

我有两个大字典:这是一个示例,但你可以想象每个字典有近100k的记录.

d1 = {'0001': [('skiing',0.789),('snow',0.65),('winter',0.56)],'0002': [('drama', 0.89),('comedy', 0.678),('action',-0.42), ('winter',-0.12),('kids',0.12)]}

d2 = {'0001': [('action', 0.89),('funny', 0.58),('sports',0.12)],'0002': [('dark', 0.89),('Mystery', 0.678),('crime',0.12), ('adult',-0.423)]}

作为最终目标,我希望有一个字典,它按每个字典的键组合值:

{'0001': [('skiing', 0.789), ('snow', 0.65), ('winter', 0.56), [('action', 0.89), ('funny', 0.58), ('sports', 0.12)]], '0002': [('drama', 0.89), ('comedy', 0.678), ('action', -0.42), ('winter', -0.12), ('kids', 0.12), [('dark', 0.89), ('Mystery', 0.678), ('crime', 0.12), ('adult', -0.423)]]}

我实现这一目标的方式是:

for key,value in d1.iteritems():
     if key in d2:
             d1[key].append(d2[key])

但是在很多地方读完后我发现iteritems()非常慢,实际上并没有使用C数据结构来实现它,而是使用python函数.如何快速有效地完成组合/合并过程.

最佳答案 如果你的输入必须是dicts,我认为你不会发现任何比iteritems更快的东西.如果一个dict的键比另一个多得多,则应该迭代较小的一个以减少迭代次数.

任何涉及将dict转换为不同数据类型的解决方案在创建时间上的成本都会比通过有效循环节省的成本更高.而不是迭代一次,你必须迭代三次(两次创建两个新集合,一次运行你的合并).

如果您在最初创建集合时可以选择使用不同的数据类型,则迭代列表(使用索引而不是键)将稍微快一些.当然,这意味着您将失去dicts可能为您提供的所有其他优势.

timeit为各种建议的方法提供以下速度,给出两个200键的序列(两个dicts的相同键):

> iteritem(给出n个问题):23.0725131035
> iterate over set intersection:31.7572350502
> concatenating Counter objects:125.085702181
>迭代列表:16.3535020351

为了给集合交叉点另一个机会,让d2的一半键实际上与d1的那些键匹配:

> iteritem:15.5433290005
> set intersection:22.1796240807

正如我们所看到的,创建两个集合的成本仍然超过任何潜在的好处(至少在Python 2中,dict.keys()给出了一个列表,而不是一个与集合操作兼容的视图).

附注:附加vs扩展

在您当前的代码示例中

for key,value in d1.iteritems():
    if key in d2:
        d1[key].append(d2[key])

您将整个d2列表作为d1中列表的单个新项目附加,而不是合并列表([1,2] .append([3,4])== [1,2,[3,4] ]],而不是[1,2,3,4]).你可以从d2遍历列表并多次调用append,但extend()会更快.

点赞