ericso
ericso

Reputation: 3308

Use a generator to create a list of dictionaries with a set of labels

Say I have a function get_call_value(row, column) that returns the value of a spreadsheet cell. I have a set of labels that correspond to the columns. I want to build a list of dictionaries, the keys of which are the column labels. Here's what I have so far:

def _get_rows(self, start_key=1):
    # List holding lists representing rows
    out_data = []

    # Get row count
    row_count = num_rows()
    column_count = num_columns()

    def get_label_value(row, column):
      """Generator for getting the cell value at row, column of an Excel sheet
      """
      labels = {
        0: 'label_1',
        1: 'label_2',
        2: 'label_3',
      }
      yield (labels[column], get_cell_value(row, column))

   return {key: value for (key, value) in get_label_value(xrange(start_key, row_count), xrange(column_count))}

My stack trace ends in an error along the lines of:

get_label_value
    yield (labels[column], get_cell_value(row, column))
KeyError: xrange(31)

I'm obviously not understanding how the generator is supposed to work. Can someone tell me what I'm doing wrong? Thanks!

Edit: I think further clarification is needed and I see an error in my logic concerning what I want to do. My expected result is a list of dictionaries. The keys in the dictionaries are the column labels and the values are the cell values at the (row, column), like so:

[
  {'label_1': value_1,
   'label_2': value_2,
   'label_3': value_3,
  },
  {
   'label_1': another_value_1,
...
  }
]

With that in mind, the return statement in my should be this then?

return [{key: value for (key, value) in get_label_value(xrange(start_key, row_count), xrange(column_count))}]

Upvotes: 0

Views: 499

Answers (1)

dano
dano

Reputation: 94881

You're trying to pass an entire xrange object to the labels dict right now, which is why you're seeing that exception. What you actually want to do is iterate over the two xrange objects you're passing to get_label_value, so that you can build your desired list of dicts:

def _get_rows(self, start_key=1):
    # List holding lists representing rows
    out_data = []

    # Get row count
    row_count = num_rows()
    column_count = num_columns()

    def get_label_value(rows, columns):
      """Generator for getting the cell value at row, column of an Excel sheet
      """
      labels = {
        0: 'label_1',
        1: 'label_2',
        2: 'label_3',
      }
      # Yield a dict for each row in the table. The dict contains all the
      # cells for a given row in the table, where the keys are column labels,
      # each mapped to a given cell in the row.
      for row in rows:
          yield {labels[column] : get_cell_value(row, column) for column in columns}

    return [cell_dict for cell_dict in get_label_value(xrange(start_key, row_count), xrange(column_count))]

Upvotes: 1

Related Questions