2016-09-11 2 views
-1

пожалуйста, помогите мне :)Группировка и сумма список словаря Python

Python 3.5

У меня есть список Dict:

[ 

    { 
     'A':'string1', 
     'B':'string_5', 
     'C':'string_9, 
     ... 
     'N':'stringN', 
     'metric1':5, 
     'metric2':7 
    }, 

    { 
    'A':'string1', 
    'B':'string_5', 
    'C':'string_11,... 
    'N':'stringN', 
    'metric1':10, 
    'metric2':45 
    }, 

    { 
    'A':'string2', 
    'B':'string_7', 
    'C':'string_15, 
     ... 
    'N':'stringN', 
    'metric1':234, 
    'metric2':78 
    }, 

    ....... 
] 

В выходной я хочу получить:

[ 

    { 
    'A':'string1', 'metric1':sum(all metric1 where 'A'='string1'), 
    'metric2':sum(all metric2 where 'A'='string1'), 
    'B': [ 

      { 
      'B':'string_5', 
      'metric1':sum(all metric1 for combination where 'A' in 
            'string1' and 'B' in string_5), 
      'metric2':sum(all metric2 , where combination Similarly 'metric1'), 
      'C':[ 

       { 
        'C':'string_9', 'metric1':sum(all metric_1 for 
      combination where 'A' in` 'string1' and 'B' in string_5 and 'C' is 'string_9'), 
        'metric2':sum(...) 
        }, 
        { 
        'C':'string_11', 
        'metric1':sum(...) 
        'metric2':sum(..) 
        } 
       ] 

      } 
     ] 
    }, 
    { 
     'A':'string_2', 'metric1':sum(all metric1 where 'A'='string2'), 
     'metric2':sum(...), 
     'B': [ 

       { 
       'B':'string_7','metric1':sum(all metric1 for 
      combination where 'A'='string_2' and 'B'='string_7'), 
       'metric2':'sum(...), 
       'C': [ 
         { 
         'C':'string_15', 
          'metric1' :sum(...), 
         'metric2':'sum(...) 
         } 
        ] 
       } 
      ] 
     }, 

.... 

    ..... 
] 

Таким образом, вывод должен группировать вход для каждой клавиши уровня (A, B, C, .. N) и суммировать все значения метрики для каждой группировки. В каждом типе родительского уровня он имеет ключ с именем следующего уровня со значением массива следующих элементов сгруппированных уровней, где родителем элементов является этот ключ.

Анинные решения?

Я попытался вызов рекурсивных функций для цикла ввода Словаря как дерево, но я получаю результат, где сгруппирован только одна ветви, и только одна ветви следующей ветви, и т.д.

+1

Пожалуйста, объясните основную идею желаемого результата, поэтому нам не нужно тратить много времени, пытаясь понять это. –

+0

@RoryDaulton Хорошо, я отредактировал мой вопрос – SmartSt

ответ

0

Мой коллеге помочь мне найти решение.

def generate_level(dicts, level, levels): 
    level2dicts = defaultdict(list) # level value -> dicts 
    for d in dicts: 
     level2dicts[d[level]].append(d) 

    if not levels: # the deepest level 
     return {level: [{level: level_value, **sum_metrics(level_dicts)} 
         for level_value, level_dicts in level2dicts.items()]} 

    inner_level, *levels = levels # pop level 
    inner_dicts = (generate_level(level_dicts, inner_level, levels) 
        for level_dicts in level2dicts.values()) 
    return {level: [{level: level_value, 
        **sum_metrics(level_dict[inner_level]), 
        **level_dict} 
        for level_value, level_dict in zip(level2dicts, inner_dicts)]} 

level, *nested_levels = order 
print(generate_level(dicts, level, nested_levels)[level]) 

'порядок' - упорядоченный список ключей (порядка уровня), 'dicts' - список вход dicts

результат:

[{'A': 'string1', 
    'B': [{'B': 'string_5', 
     'C': [{'C': 'string_9', 'metric1': 5, 'metric2': 7}, 
       {'C': 'string_11', 'metric1': 10, 'metric2': 45}], 
     'metric1': 15, 
     'metric2': 52}], 
    'metric1': 15, 
    'metric2': 52}, 
{'A': 'string2', 
    'B': [{'B': 'string_7', 
     'C': [{'C': 'string_15', 'metric1': 234, 'metric2': 78}], 
     'metric1': 234, 
     'metric2': 78}], 
    'metric1': 234, 
    'metric2': 78}] 

Спасибо всем, кто минус мой вопрос! @Rory Daulton

Смежные вопросы