【问题标题】:Python Collections Counter for a List of Dictionaries字典列表的 Python 集合计数器
【发布时间】:2015-04-08 17:28:38
【问题描述】:

我有一个动态增长的数组列表,我想将类似的值添加在一起。这是一个例子:

{"something" : [{"one":"200"}, {"three":"400"}, {"one":"100"}, {"two":"800"} ... ]}

我希望能够将列表中的字典加在一起。因此,在这种情况下,对于关键“某物”,结果将是:

["one":400, "three": 400, "two": 800]

或类似的东西。我对 Python 的收集计数器很熟悉,但是由于“某物”列表包含字典,所以它不起作用(除非我遗漏了某些东西)。字典也是动态创建的,所以我无法在没有字典的情况下构建列表。例如:

Counter({'b':3, 'c':4, 'd':5, 'b':2})

正常工作,但只要我尝试添加一个元素,之前的值就会被覆盖。我注意到其他问题,例如:

Is there any pythonic way to combine two dicts (adding values for keys that appear in both)?

Python count of items in a dictionary of lists

但同样,列表中的对象是字典。

【问题讨论】:

  • 你的结构有点混乱;您有一个外部字典,其值是字典列表,每个字典只有一个键?我们需要担心外部字典中有很多实际条目吗?或者我们只是在"something" 键的内部列表中添加字典?一个更完整的预期输入和输出示例会很有帮助。
  • @aruisdante 很抱歉造成混乱。结构非常令人沮丧,但除了修改它之外,我无法控制它。回答您的问题: 1) 是的,每个只有一把钥匙。 2)可能还有其他字典,例如史蒂夫杰索普的回答说明。

标签: python list python-2.7 dictionary collections


【解决方案1】:

我认为这可以满足您的要求,但我不确定,因为我不知道“字典也在动态创建,所以我无法在没有字典的情况下构建列表”是什么意思。还是:

input = {
    "something" : [{"one":"200"}, {"three":"400"}, {"one":"100"}, {"two":"800"}], 
    "foo" : [{"a" : 100, "b" : 200}, {"a" : 300, "b": 400}],
}

def counterize(x):
    return Counter({k : int(v) for k, v in x.iteritems()})

counts = {
    k : sum((counterize(x) for x in v), Counter()) 
    for k, v in input.iteritems()
}

结果:

{
    'foo': Counter({'b': 600, 'a': 400}), 
    'something': Counter({'two': 800, 'three': 400, 'one': 300})
}

我希望将sumCounter 一起使用是低效的(就像将sum 与字符串一起使用效率非常低,以至于Guido 禁止了它),但我可能错了。无论如何,如果你有性能问题,你可以编写一个函数来创建一个Counter 并在其上重复调用+=update

def makeints(x):
    return {k : int(v) for k, v in x.iteritems()}

def total(seq):
    result = Counter()
    for s in seq:
        result.update(s)
    return result

counts = {k : total(makeints(x) for x in v) for k, v in input.iteritems()}

【讨论】:

    【解决方案2】:

    一种方法如下:

    from collections import defaultdict
    
    d = {"something" :
         [{"one":"200"}, {"three":"400"}, {"one":"100"}, {"two":"800"}]}
    
    dd = defaultdict(list)
    
    # first get and group values from the original data structure
    # and change strings to ints
    for inner_dict in d['something']:
        for k,v in inner_dict.items():
            dd[k].append(int(v))
    
    
    # second. create output dictionary by summing grouped elemetns
    # from the first step.
    out_dict =  {k:sum(v) for k,v in dd.items()}
    
    print(out_dict)
    # {'two': 800, 'one': 300, 'three': 400}
    

    这里我不使用计数器,而是使用defaultdict。它是一个两步的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-08
      • 2016-04-27
      • 1970-01-01
      • 2021-10-06
      • 2012-08-11
      • 2012-07-17
      • 2015-09-18
      相关资源
      最近更新 更多