penitent_tangent
penitent_tangent

Reputation: 772

Aggregating / grouping lists into a dictionary

I have a list - let's call it 'catalog' - of object properties. Different objects can have a different number of properties; for example items 1 and 2 have "colour" and "sizeid", but item 3 has an additional "onsale" property.

[{'item_id': 1, 'property_name': 'colour', 'property_value': 'blk'},
 {'item_id': 1, 'property_name': 'sizeid', 'property_value': '1'},
 {'item_id': 2, 'property_name': 'colour', 'property_value': 'grn'},
 {'item_id': 2, 'property_name': 'sizeid', 'property_value': '2'},
 {'item_id': 3, 'property_name': 'colour', 'property_value': 'blue'},
 {'item_id': 3, 'property_name': 'sizeid', 'property_value': '2'},
 {'item_id': 3, 'property_name': 'onsale', 'property_value': True}]

I would like to be able to access property_value based on item_id and property_name, like so:

>>> print catalog[1]['sizeid']
>>> '1'
>>> print catalog[3]['onsale']
>>> True
>>> print catalog[2]['onsale']
>>> KeyError: 'onsale'

I had a cunning plan to do this procedurally with something like

for i, val in enumerate(catalog):
    tidy_catalog[val['item_id']][val['property_name']] = val['property_value']

But this hasn't worked - probably for many reasons, but I think primarily because dictionaries won't allow duplicate values.

Appreciate any suggestions, or even helpful man pages - I am stuck in PHP ways of thinking and while I think I get Python data structures at a conceptual level, using them in practice is proving a bit challenging.

Upvotes: 0

Views: 26

Answers (2)

stranac
stranac

Reputation: 28256

The reason this hasn't worked is assigning values to keys which do not exist.
To get around this probem, you can use a defaultdict:

>>> tidy_catalog = collections.defaultdict(dict)
>>> for val in catalog:
...     tidy_catalog[val['item_id']][val['property_name']] = val['property_value']
...
>>> pp(tidy_catalog)
defaultdict(<type 'dict'>, {
    1: {'colour': 'blk', 'sizeid': '1'},
    2: {'colour': 'grn', 'sizeid': '2'},
    3: {'colour': 'blue', 'onsale': True, 'sizeid': '2'},
})

Upvotes: 1

PatNowak
PatNowak

Reputation: 5812

Consider adjusting your catalog array to array of proper dictionaries, where you store these informations:

catalog = [{'item_d' : 1, 'colour' : 'blk', 'sizeid' : '1'}, ...]

Upvotes: 0

Related Questions