【问题标题】:How to use Counter with a list of dicts in python如何在python中使用带有字典列表的Counter
【发布时间】:2018-04-04 16:13:22
【问题描述】:

拥有这样的列表,我可以通过以下方式获取相同值的组:

N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
C = Counter(N)
print([[k, ] * v for k, v in C.items()])

得到以下结果。

[[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]

但是,如果我有以下列表

N = [{'doc':'A','value':300,'W':1},{'doc':'B','value':301,'W':0.5},{'doc':'C','value':301,'W':0.45},{'doc':'D','value':301,'W':0.3},{'doc':'E','value':300,'W':1},]

我想按照和上一个一样的方式进行分组,使用键'value'进行分组,即:

[[{'doc':A,'value':300,'W':1}, {'doc':'E','value':300,'W':1}],[{'doc':'B','value':301,'W':0.5},{'doc':'C','value':301,'W':0.45},{'doc':'D','value':301,'W':0.3}]]

有人可以帮忙吗?

【问题讨论】:

    标签: python list dictionary counter


    【解决方案1】:

    你可以使用collections.defaultdict来解决这个问题。

    collections.Counter 仅对递增整数计数器有用,即使如此 only with hashable objects。这不是您要在此处执行的操作。

    from collections import defaultdict
    
    N = [{'doc':'A','value':300,'W':1}, {'doc':'B','value':301,'W':0.5},
         {'doc':'C','value':301,'W':0.45}, {'doc':'D','value':301,'W':0.3},
         {'doc':'E','value':300,'W':1},]
    
    d = defaultdict(list)
    
    for i in N:
        d[i['value']].append(i)
    
    res = list(d.values())
    
    # [[{'W': 1, 'doc': 'A', 'value': 300}, {'W': 1, 'doc': 'E', 'value': 300}],
    #  [{'W': 0.5, 'doc': 'B', 'value': 301},
    #   {'W': 0.45, 'doc': 'C', 'value': 301},
    #   {'W': 0.3, 'doc': 'D', 'value': 301}]]
    

    顺便说一句,这也为您的第一个问题提供了更直接的解决方案:

    N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
    
    d = defaultdict(list)
    
    for i in N:
        d[i].append(i)
    
    res = list(d.values())
    
    # [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
    

    【讨论】:

      【解决方案2】:

      这不能用计数器来完成,原因有很多:

      1. 整数是可散列的,而字典则不是。 Counter 仅适用于可散列值。
      2. 所有分组的整数都相同,但字典不同。只有您要分组的字典的“值”键是相同的。即使Counter 使用字典,它也只会保留每组 1 个字典并丢弃其余的。

      这里的解决方案是使用defaultdict 而不是Counter

      from collections import defaultdict
      
      N = [{'doc':'A','value':300,'W':1},{'doc':'B','value':301,'W':0.5},
           {'doc':'C','value':301,'W':0.45},{'doc':'D','value':301,'W':0.3},
           {'doc':'E','value':300,'W':1}]
      
      groups = defaultdict(list)
      for dic in N:
          groups[dic['value']].append(dic)
      
      result = list(groups.values())
      # [[{'W': 1, 'doc': 'A', 'value': 300}, {'W': 1, 'doc': 'E', 'value': 300}],
      #  [{'W': 0.5, 'doc': 'B', 'value': 301},
      #   {'W': 0.45, 'doc': 'C', 'value': 301},
      #   {'W': 0.3, 'doc': 'D', 'value': 301}]]
      

      【讨论】:

        【解决方案3】:

        没有任何导入的简单手动方法怎么样:

        N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
        
        d={}
        
        for i,j in enumerate(N):
            if j not in d:
                d[j]=[j]
            else:
                d[j].append(j)
        
        print(d)
        

        输出:

        {1: [1], 2: [2, 2], 3: [3, 3, 3], 4: [4, 4, 4, 4], 5: [5, 5, 5, 5, 5]}
        

        或:

        print(d.values())
        

        输出:

        [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-21
          • 2018-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-09
          • 1970-01-01
          相关资源
          最近更新 更多