Jamie
Jamie

Reputation: 7431

Can I use set comprehension to create a list of dict from a bigger list of dict?

I'm working with denormalized tables which provides a bit of challenge when it comes to extracting unique information. If the tables were normalized:

unique_data = list({d['value'] for d in mydata})

would do the trick.

But the tables aren't normalized.

Can I create a set of dict that I can then turn into list? Something like (this gives me an error):

unique_data_with_id = list({{'id':d['id'], 'value':d['value']} for d in mydata})

Upvotes: 2

Views: 124

Answers (3)

DSM
DSM

Reputation: 353449

More because it's occasionally useful in other contexts, you could use a frozenset as an intermediate object:

>>> pprint.pprint(mydata)
[{'id': 1, 'ignore': 92, 'value': 'a'},
 {'id': 2, 'ignore': 92, 'value': 'b'},
 {'id': 1, 'ignore': 92, 'value': 'a'}]
>>> keep_keys = "id", "value"
>>> [dict(s) for s in {frozenset((k, d[k]) for k in keep_keys) for d in mydata}]
[{'id': 1, 'value': 'a'}, {'id': 2, 'value': 'b'}]

Upvotes: 0

Veedrac
Veedrac

Reputation: 60207

{{'id':d['id'], 'value':d['value']} for d in mydata}

creates a set ofdicts. Because dicts are mutable, they aren't hashable and a set needs hashable elements.

Try tuple instead:

{(d['id'], d['value']) for d in mydata}

Note that I quite like Sven Marnach's usage of a namedtuple here.

Upvotes: 0

Sven Marnach
Sven Marnach

Reputation: 602425

Dictionaries are mutable, so you can't put them in a set. One way around this is to use a namedtuple instead of a dictionary:

IdValueTuple = collections.namedtuple("IdValueTuple", "id value")
unique_data_with_id = list({IdValueTuple(d["id"], d["value"]) for d in mydata})

Upvotes: 5

Related Questions