【问题标题】:Cleanest way to sum list of nested dicts对嵌套字典列表求和的最简洁方法
【发布时间】:2019-05-16 21:10:21
【问题描述】:

有没有一种更简洁/更 Pythonic 的方式来总结嵌套字典列表的内容?这是我正在做的事情,但我怀疑可能有更好的方法:

list_of_nested_dicts = [{'class1': {'TP': 1, 'FP': 0, 'FN': 2}, 'class2': {'TP': 0, 'FP': 0, 'FN': 0}, 'class3': {'TP': 0, 'FP': 0, 'FN': 0}, 'class4': {'TP': 1, 'FP': 0, 'FN': 2}},
                        {'class1': {'TP': 1, 'FP': 0, 'FN': 2}, 'class2': {'TP': 0, 'FP': 0, 'FN': 0}, 'class3': {'TP': 0, 'FP': 0, 'FN': 0}, 'class4': {'TP': 1, 'FP': 0, 'FN': 2}},
                        {'class1': {'TP': 1, 'FP': 0, 'FN': 2}, 'class2': {'TP': 0, 'FP': 0, 'FN': 0}, 'class3': {'TP': 0, 'FP': 0, 'FN': 0}, 'class4': {'TP': 1, 'FP': 0, 'FN': 2}},
                        {'class1': {'TP': 1, 'FP': 0, 'FN': 2}, 'class2': {'TP': 0, 'FP': 0, 'FN': 0}, 'class3': {'TP': 0, 'FP': 0, 'FN': 0}, 'class4': {'TP': 1, 'FP': 0, 'FN': 2}}]

total_counts = {k:{'TP': 0, 'FP': 0, 'FN': 0} for k in list_of_nested_dicts[0].keys()}

for d in list_of_nested_dicts:
    for label,counts_dict in d.items():
        for k,v in counts_dict.items():
            total_counts[label][k] += v

print(total_counts)

(假设所有键完全相同,但值可以是任何整数)

【问题讨论】:

  • 老实说,这很不错。也许可以将total_counts 切换为默认字典,但坦率地说,我真的不明白为什么这不好。
  • 或收款柜台。 list_of_nested_dicts[0].keys() 可以是 list_of_nested_dicts[0]

标签: python list dictionary nested python-3.6


【解决方案1】:

您可以使用collections 获得稍微紧凑的代码(与@blhsing 的结果相似)

import collections

counts = collections.defaultdict(collections.Counter)
for d in list_of_nested_dicts:
    for k, v in d.items():
        counts[k].update(v)

这将为您提供计数器的默认字典,而不仅仅是字典,但它们的行为相似。如果需要,您还可以在最后将它们显式转换为 dicts。

{'class1': {'FN': 8, 'FP': 0, 'TP': 4},
 'class2': {'FN': 0, 'FP': 0, 'TP': 0},
 'class3': {'FN': 0, 'FP': 0, 'TP': 0},
 'class4': {'FN': 8, 'FP': 0, 'TP': 4}}

defaultdict(<class 'collections.Counter'>,
            {'class1': Counter({'FN': 8, 'TP': 4, 'FP': 0}),
             'class2': Counter({'TP': 0, 'FP': 0, 'FN': 0}),
             'class3': Counter({'TP': 0, 'FP': 0, 'FN': 0}),
             'class4': Counter({'FN': 8, 'TP': 4, 'FP': 0})})

【讨论】:

    【解决方案2】:

    您的代码中突出为“不干净”的一件事是您在 total_counts 的初始化中对子字典的键进行了硬编码。您可以通过使用 dict.setdefaultdict.get 方法来避免这种硬编码,因为您可以迭代子字典的项目:

    total_counts = {}
    for d in list_of_nested_dicts:
        for label, counts_dict in d.items():
            for k, v in counts_dict.items():
                total_counts[label][k] = total_counts.setdefault(label, {}).get(k, 0) + v
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      相关资源
      最近更新 更多