【问题标题】:List comprehension in list of dictionaries [duplicate]字典列表中的列表理解[重复]
【发布时间】:2019-04-05 15:01:13
【问题描述】:

我有以下字典列表:

allChannelTraffic = [ { "Web" : 4, "android" : 3 }, { "Web" : 1 }, { "Web" : 1 }, { "Web" : 1 },]

我想知道从上面的列表中获得这样的输出的最简单方法:

[{'Web':7,'android':3}]  

我想在哪里获得所有键的值的总和。听说在python中使用列表推导,我们可以很方便的进行操作。有人可以告诉我如何使用列表理解来实现吗?

【问题讨论】:

  • @DavidG 不是真的,因为 android 键不会出现在每个字典中

标签: python


【解决方案1】:

您可以将Countersum 一起使用:

from collections import Counter

allChannelTraffic = [{"Web": 4, "android": 3}, {"Web": 1}, {"Web": 1}, {"Web": 1}, ]

result = sum(map(Counter, allChannelTraffic), Counter())

print(result)

输出

Counter({'Web': 7, 'android': 3})

【讨论】:

    【解决方案2】:

    列表推导在这里并不是很有用。

    生成器表达式允许我们执行以下操作:

    allChannelTraffic = [ { "Web" : 4, "android" : 3 }, { "Web" : 1 }, { "Web" : 1 }, { "Web" : 1 },]
    keys = set(k for d in allChannelTraffic for k in d.keys())
    totals = {key: sum(d.get(key, 0) for d in allChannelTraffic) for key in keys}
    print(totals)
    
    # {'Web': 7, 'android': 3}
    

    顺便说一句,最后一个{key: sum([...]) for key in keys} 是字典理解。

    我本可以在第 2 行中使用集合理解而不是 set()

    {k ... for k in d.keys()} == set(k ... for k in d.keys())

    但我不想那样做,因为set() 对读者来说更清楚。

    一般来说,尽管对于没有经验的 pythonistas 来说,针对您的问题的 Counter 或 Defaultdict 方法可能更容易理解......

    【讨论】:

      【解决方案3】:

      您可以使用collections.defaultdict 来汇总每个键的值

      import collections
      totals = collections.defaultdict(int)
      for sub in allChannelTraffic:
          for key, value in sub.items():
              totals[key] += value
      

      输出

      >>> totals
      defaultdict(<class 'int'>, {'android': 3, 'Web': 7})
      

      【讨论】:

      • 不错的答案,但只是因为他想要一个列表理解,这里是:[totals[key] += value for key, value in sub.items() for sub in allChannelTraffic] 不要抢你的风头,我只是喜欢一个班轮 :)
      • @Jaba 不起作用,因为密钥不存在并且会引发错误
      • 这是一个默认字典。我可能错了..
      【解决方案4】:

      这不是列表推导,但您始终可以在此处使用 Counter.update()

      from collections import Counter
      
      allChannelTraffic = [ { "Web" : 4, "android" : 3 }, { "Web" : 1 }, { "Web" : 1 }, { "Web" : 1 }]
      
      counts = Counter()
      for d in allChannelTraffic:
          counts.update(d)
      
      print(counts)
      # Counter({'Web': 7, 'android': 3})
      

      非库方法看起来像这样:

      allChannelTraffic = [ { "Web" : 4, "android" : 3 }, { "Web" : 1 }, { "Web" : 1 }, { "Web" : 1 }]
      
      counts = {}
      for d in allChannelTraffic:
          for k in d:
              counts[k] = counts.get(k, 0) + d[k]
      
      print(counts)
      # Counter({'Web': 7, 'android': 3})
      

      【讨论】:

        【解决方案5】:
        allChannelTraffic = [ { "Web" :4,"android" : 3 }, { "Web" : 1 }, { "Web" : 1 },{ "Web" : 1 },] 
        allChannelTraffic = [{"web": sum([item[1].get("Web",0) for item in enumerate(allChannelTraffic)]), "android":sum([item[1].get("android",0) for item in enumerate(allChannelTraffic)])}]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-23
          • 2018-03-18
          • 2016-11-09
          • 2022-12-13
          • 2021-03-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多