0

I am using Python3, I'm currently trying to refactor some code and this in particular looks a bit sloppy. Right now I have a standard for loop going though the list of tuples and pairing them with hard coded keys.

    values = [
        (1, 'test1', 15.5),
        (2, 'test2', 31.67),
        (3, 'item1', 16.5),
        (4, 'bike1', 15.5),
    ]

    keys = ['id', 'name', 'price']

    items = []

    for row in values:
        items.append({'id': row[0], 'name': row[1], 'price': row[2]})

    return items

Here is a similar article More efficient way to create JSON from Python

However I'm having a hard time figuring how how to handle the fact my two sets of data are pretty different

    items = [row for row in result]
    columns = [key[0] for key in cursor.description]

    print([{key: val} for key, val in zip(columns, items)] )

I cam up with this, which could be condensed into one line theoretically. But since my data isn't 1 for 1 ( i.e. a list vs a list of tupels ) it gives me this...

[{'id': (1, 'bike2', 15.5)}, {'name': (2, 'test', 31.67)}, {'price': (3, 'bike3', 15.5)}]

UPDATE

Here was my final solution, thanks Martijn!

items = [dict(zip([key for key in keys], row)) for row in result]

1 Answers1

1

You were almost there; you need to zip individual rows, not all rows at once:

[dict(columns, row) for row in result]

However, you can simply tell sqlite to produce dictionaries for each row, by setting the row_factory:

def dict_factory(cursor, row):
    return {d[0]: col for d, col in zip(cursor.description, row)}

connection.row_factory = dict_factory

at which point you simply return the cursor results as a list:

return cursor.fetch_all()
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343