在词典列表中添加元素

时间:2010-07-29 19:20:05

标签: python dictionary nested

我有很长的字典列表,包含字符串索引和整数值。字典中的许多键都是相同的,但不是全部。我想生成一个字典,其中键是单独字典中键的并集,值是每个字典中与该键对应的所有值的总和。 (例如,组合字典中键'apple'的值将是第一个中'apple'值的总和加上第二个中'apple'值的总和等。)

我有以下内容,但它相当繁琐,需要年龄才能执行。有没有更简单的方法来实现相同的结果?

comb_dict = {}  
for dictionary in list_dictionaries:  
    for key in dictionary:  
        comb_dict.setdefault(key, 0)  
        comb_dict[key] += dictionary[key]  
return comb_dict

4 个答案:

答案 0 :(得分:9)

以下是一些微观基准,表明f2(见下文)可能会有所改进。 f2使用iteritems,可以避免在内循环中进行额外的dict查找:

import collections
import string
import random

def random_dict():
    n=random.randint(1,26)
    keys=list(string.letters)
    random.shuffle(keys)
    keys=keys[:n]
    values=[random.randint(1,100) for _ in range(n)]    
    return dict(zip(keys,values))

list_dictionaries=[random_dict() for x in xrange(100)]

def f1(list_dictionaries):
    comb_dict = {}  
    for dictionary in list_dictionaries:  
        for key in dictionary:  
            comb_dict.setdefault(key, 0)  
            comb_dict[key] += dictionary[key]  
    return comb_dict

def f2(list_dictionaries):    
    comb_dict = collections.defaultdict(int)
    for dictionary in list_dictionaries:  
        for key,value in dictionary.iteritems():  
            comb_dict[key] += value
    return comb_dict

def union( dict_list ):
    all_keys = set()
    for d in dict_list:
        for k in d:
            all_keys.add( k )
    for key in all_keys:
        yield key, sum( d.get(key,0) for d in dict_list)

def f3(list_dictionaries):
    return dict(union( list_dictionaries ))

结果如下:

% python -mtimeit -s"import test" "test.f1(test.list_dictionaries)"
1000 loops, best of 3: 776 usec per loop
% python -mtimeit -s"import test" "test.f2(test.list_dictionaries)"
1000 loops, best of 3: 432 usec per loop    
% python -mtimeit -s"import test" "test.f3(test.list_dictionaries)"
100 loops, best of 3: 2.19 msec per loop

答案 1 :(得分:1)

改为使用collections.defaultdict

http://docs.python.org/library/collections.html#defaultdict-objects

稍微简单一些。

答案 2 :(得分:1)

这也可能很快,但这实际上取决于您的数据。它避免了所有变化的词汇或额外的列表 - 只有一组所有键和大量的读取: - )

from itertools import chain

def union( dict_list ):
    all_keys = set(chain.from_iterable(dict_list))
    for key in all_keys:
        yield key, sum( d.get(key,0) for d in dict_list)

combined = dict(union( dict_list ))

答案 3 :(得分:0)

你可以从google的map-reduce中获得灵感。据我所知,它旨在解决这类问题。