【问题标题】:Creating Python defaultdict using nested list of tuples使用嵌套的元组列表创建 Python defaultdict
【发布时间】:2019-04-16 10:46:19
【问题描述】:

场景是我有一个二维列表。内部列表的每一项都是元组(键,值对)。该键可能在列表中重复。我想动态创建一个默认字典,最终字典存储键,以及二维列表中该键的所有值的累积和。

放代码:

listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
finalDict = defaultdict(int)
for eachItem in listOfItems:
    for key, val in eachItem:
        finalDict[key] += val
print(finalDict)

这给了我我想要的东西:defaultdict(<class 'int'>, {'a': 7, 'b': 5, 'c': 0, 'd': 5}) 但我正在寻找一种使用理解的更“Pythonic”的方式。所以我尝试了以下方法:

finalDict = defaultdict(int)
finalDict = {key : finalDict[key]+val for eachItem in listOfItems for key, val in eachItem}
print(finalDict)

但输出是:{'a': 6, 'b': 2, 'c': 0, 'd': 5} 我做错了什么?或者是不是在使用理解时字典不是动态创建和修改的?

【问题讨论】:

    标签: python python-3.x nested-lists defaultdict dictionary-comprehension


    【解决方案1】:

    尝试使用 python 的内置方法而不是自己编写功能:

    详细解释的解决方案

    from itertools import chain, groupby
    from operator import itemgetter
    
    listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
    
    # just flat the list of lists into 1 list..
    flatten_list = chain(*listOfItems)
    
    # get all elements grouped by the key, e.g 'a', 'b' etc..
    first = itemgetter(0)
    groupedByKey = groupby(sorted(flatten_list, key=first), key=first))
    
    #sum
    summed_by_key = ((k, sum(item[1] for item in tups_to_sum)) for k, tups_to_sum in groupedByKey)
    
    # create a dict
    d = dict(summed_by_key)
    
    print(d) # {'a': 7, 'b': 5, 'c': 0, 'd': 5}
    

    ~单线解决方案

    from itertools import chain, groupby
    from operator import itemgetter
    
    first = itemgetter(0)
    d = dict((k, sum(item[1] for item in tups_to_sum)) for k, tups_to_sum in groupby(sorted(chain(*listOfItems), key=first), key=first))
    
    print(d) # {'a': 7, 'b': 5, 'c': 0, 'd': 5}
    

    【讨论】:

      【解决方案2】:

      不使用额外模块的简单解决方案:

      inp_list = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
      
      l = [item for sublist in inp_list for item in sublist] # flatten the list
      
      sums = [(key, sum([b for (a,b) in l if a == key])) for key in dict(l)]
      
      print(sums)
      

      【讨论】:

      • 请注意,您可以使用 itertools.chain(*inp_list) 来展平列表
      【解决方案3】:

      这是因为您没有在理解中为您的 dict 中的 finalDict 分配任何值。

      在您的理解中,您实际上是在更改 finalDict 的类型

      据我所知,您无法在理解的字典中为您的字典赋值。

      这是获取所需词典的一种方法

      from functools import reduce
      
      listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
      
      list_dict = [{key: val} for eachItem in listOfItems for key, val in eachItem]
      
      def sum_dict(x, y):
          return {k: x.get(k, 0) + y.get(k, 0) for k in set(x) | set(y)}
      print(reduce(sum_dict, list_dict))
      

      【讨论】:

        【解决方案4】:

        是的,理解不能即时更新。无论如何,这个任务可能更适合 collections.Counter().update() 调用:

        >>> from collections import Counter
        >>> c = Counter()
        >>> for eachItem in listOfItems:
        ...     c.update(dict(eachItem))
        ... 
        >>> c
        Counter({'a': 7, 'b': 5, 'd': 5, 'c': 0})
        

        【讨论】:

        • 好的.. 我应该提到,列表中的值也可以是浮动的。我错过了这一点,试图简化我的问题。有什么方法可以处理@Chris_Rands?感谢您的帮助..!
        猜你喜欢
        • 2016-04-07
        • 1970-01-01
        • 2013-10-11
        • 1970-01-01
        • 2015-04-29
        • 1970-01-01
        相关资源
        最近更新 更多