0

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

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

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 个条目),是否有更快的方法?

4

3 回答 3

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
    

当字段的数量远大于每个键的数量时,这应该会更快dict,因为它会跳过哈希查找,并且可以一次性构建列表,而不是在遍历fields. (不过,后一种优化也可以应用于您当前的算法。)

在将它应用到实际代码之前,请务必对其进行基准测试,因为实际性能取决于很多因素,包括哈希函数的速度(以及实际的键)和dict执行的过度分配。

于 2013-02-28T17:10:50.203 回答
0

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

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

for value in value_iterator:
    #Do something.

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

于 2013-02-28T17:17:02.710 回答
-1

使用collections.Counter.

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

然后你可以这样做:

counts = cntr.most_common()

这为您提供了一个元组列表,您可以将其列出 comprehend-ify。

但正如评论者所提到的,您的解决方案非常好。

于 2013-02-28T16:49:02.853 回答