title: Python. Calculate dimension totals for list of dictionaries
body: <h1>I have 2 dimensions:</h1>
  
  <pre><code>dimensions = ('product', 'place')
  </code></pre>
  
  <h1>And 2 metrics:</h1>
  
  <pre><code>metrics = ('METRIC_1', 'METRIC_2')
  </code></pre>
  
  <h1>Input is the following list of dicts with dimensions and metrics</h1>
  
  <pre><code>input = [
      {'product': 'eggs', 'place': 'fridge', 'METRIC_1': 1, 'METRIC_2': 2},
      {'product': 'eggs', 'place': 'table', 'METRIC_1': 3, 'METRIC_2': 1},
      {'product': 'ham', 'place': 'fridge', 'METRIC_1': 1, 'METRIC_2': 2},
      {'product': 'ham', 'place': 'table', 'METRIC_1': 3, 'METRIC_2': 5},
  ]
  </code></pre>
  
  <p>For each dimension and all combination of dimensions I want to get '_all_' value, where metrics are summed up (or applied any other aggregation method).</p>
  
  <h1>Expected result:</h1>
  
  <pre><code>result = [
      {'product': '_all_', 'place': 'fridge', 'METRIC_1': 2, 'METRIC_2': 4},
      {'product': '_all_', 'place': 'table', 'METRIC_1': 6, 'METRIC_2': 6},
      {'product': 'eggs', 'place': '_all_', 'METRIC_1': 4, 'METRIC_2': 3},
      {'product': 'ham', 'place': '_all_', 'METRIC_1': 4, 'METRIC_2': 7},
      {'product': '_all_', 'place': '_all_', 'METRIC_1': 8, 'METRIC_2': 8},
  ]
  </code></pre>
  
  <p>Consider that number of dimensions and metrics is flexible.
  Would appreciate, if the answer is a function with the following signature:</p>
  
  <pre><code>calc_totals(input_list, dimensions_list, {'metric_1': 'sum', 'metric_2': 'sum'}):
      pass
  </code></pre>
  
  <p>My attempt follows, but seems too complicated and not sure if it's right:</p>
  
  <pre><code>from operator import itemgetter
  from itertools import groupby, combinations, chain
  
  
  def powerset(iterable):
      xs = list(iterable)
      return chain.from_iterable(combinations(xs, n) for n in range(len(xs)+1))
  
  
  def calc_totals(input, dimensions):
      totals = []
      dim_combs = list(powerset(dimensions))[1:-1]
      for dim_comb in dim_combs:
          current_dims = dimensions.difference(set(dim_comb))
          grouper = itemgetter(*current_dims)
          for key, group in groupby(sorted(input, key=grouper), grouper):
              temp_dict = dict(zip(list(current_dims), [key]))
  
              temp_dict['METRIC_1'] = 0
              temp_dict['METRIC_2'] = 0
              for item in group:
                  temp_dict['METRIC_1'] += item['METRIC_1']
                  temp_dict['METRIC_2'] += item['METRIC_2']
  
              for dim in dim_comb:
                  temp_dict[dim] = '_all_'
              totals.append(temp_dict)
      return totals
  </code></pre>