从稀疏字典和密钥列表构建列表的最快方法

时间:2013-02-28 16:45:14

标签: python

我确信有一种简单的方法可以做到这一点,但我遇到了困难。

我有一个字段名称列表,例如

fields = ['foo', 'bar', 'baz']

我有(很多)字典使用其中一些名称:

values = {'foo': 1, 'baz': 2}

我想要的是将这个字典转换为值的列表,在正确的位置匹配字段列表,即:

value_list = [1, None, 2]

到目前为止,我最好的解决方案是:

value_list = [values.get(field) for field in fields]

但使用zip还是有更好的方法吗?

特别是,如果我有一长串“价值词典”(比如10000),并且它们非常稀疏(比如说,字段长200,但每个“值字典”只有大约10个条目),有更快的方法吗?

3 个答案:

答案 0 :(得分:2)

  

特别是,如果我有一长串“价值词典”(比如10000),并且它们非常稀疏(比如说,字段长200,但每个“值字典”只有大约10个条目),有更快的方法吗?

可能。

  1. 构建将键映射到其预期索引的字典:

    idx = dict((k, i) for i, k in enumerate(fields))
    

    这是一个预处理步骤,您只应对整批字典执行一次。

  2. 现在遍历字典键而不是字段:

    lst = [None] * len(fields)
    for k, v in values.iteritems():
        lst[idx[k]] = v
    
  3. 当字段数远远大于每dict个键的数量时,这应该更快,因为它会跳过哈希查找并且可以在遍历{{1}期间一次性构建列表而不是动态构建列表}。 (但后一种优化也可以应用于您当前的算法中。)

    在实际代码中应用它之前,请务必对其进行基准测试,因为实际性能取决于很多因素,包括散列函数的速度(以及实际的密钥)和fields的过度分配进行。

答案 1 :(得分:0)

根据您完成清单后要对列表执行的操作,您可以考虑使用生成器。这不会减少任何操作,但它可能会节省您构建不必要的列表。

value_iterator = (values.get(field) for field in fields) # Python>=2.7

for value in value_iterator:
    #Do something.

这样,在遍历值的“列表”之前,不会执行任何操作。

答案 2 :(得分:-1)

使用collections.Counter

import collections as col
cntr = col.Counter(your_list)

然后你可以这样做:

counts = cntr.most_common()

这将为您提供一个元组列表,您可以列出这些元组的理解。

但是正如评论者所说,你的解决方案非常好。