I don't think there is any easy to read, pithy 1-liner for this (though it's probably not hard to come up with a difficult to read, pithy 1-liner ... ;) -- at least not in the general case (arbitrary number of dict items where the keys are unknown).
If you know the keys of the dict, I think it's probably easiest to work with that (especially since there are only 2 of them in the example).
Build the new dicts in 2 passes. The first pass fills in x
, the second pass fills in y
.
new_dicts = [{'x': x} for x in d['x']]
for new_dict, y in zip(new_dicts, d['y']):
new_dict['y'] = y
If you'd rather do it in 1 pass, I think this isn't too bad either:
new_dicts = [{'x': x, 'y': y} for x, y in zip(d['x'], d['y'])]
If you have a list of keys, I might do it slightly differently ...
import operator
value_getter = operator.itemgetter(*list_of_keys)
new_dicts_values = zip(*value_getter(d))
new_dicts = [
dict(zip(list_of_keys, new_dict_values))
for new_dict_values in new_dicts_values]
This is pretty much the same strategy taken in Martijn's answer ... However, I think that breaking it out a little and giving things names helps make it a little more clear what is going on. Also, this takes away the mental overhead of having to convince yourself that zipping an unordered dict
with an unordered list of column values is OK since they're unordered in the same way...
And, of course, if you don't actually have a list of keys, you can always get one by
list_of_keys = list(d)
'x', 'y', 'z'
as keys. I have a list, sayl = [ 'x', 'y', 'z' ]
though – Linnea